Add release notes for 0.33 (#1939)
Co-authored-by: Jen Basch <jbasch@apple.com> Co-authored-by: Dan Chao <dan.chao@apple.com>
This commit is contained in:
2 files changed
+532
-37
No files matched your search
@@ -3364,6 +3364,7 @@ The value will not have property `isPredatory = true` as the `default` property
|
||||
<3> Assigning a `new` explicitly-typed value to a `Mapping` entry.
|
||||
The value will not have property `isPredatory = true` as the `default` property of the `Mapping` is not used.
|
||||
|
||||
[[implicitly-typed-new]]
|
||||
==== Implicitly Typed `new`
|
||||
|
||||
When using the implicitly typed `new` invocation, there is no explicit parent value to amend.
|
||||
@@ -3371,6 +3372,8 @@ In these cases, Pkl infers the amend operation's parent value based on context:
|
||||
|
||||
* When assigning to a declared property, the property's default value is amended (<<amend-null, including `null`>>).
|
||||
If there is no type associated with the property, an empty `Dynamic` object is amended.
|
||||
* In method argument, method return value, and let binding positions, the annotated type's default value is amended.
|
||||
If there is no type annotation, an empty `Dynamic` object is amended.
|
||||
* When assigning to an entry (e.g. a `Mapping` member) or element (e.g. a `Listing` member), the enclosing object's `default` property is applied to the corresponding index or key, respectively, to produce the value to be amended.
|
||||
* In other cases, evaluation fails with the error message "Cannot tell which parent to amend".
|
||||
|
||||
@@ -3382,29 +3385,29 @@ In this case, the argument's type should be specified explicitly.
|
||||
class Bird {
|
||||
name: String
|
||||
|
||||
function listHatchlings(items: Listing<String>): Listing<String> = new {
|
||||
function listHatchlings(items: Listing<String>): Listing<String> = new { // <1>
|
||||
for (item in items) {
|
||||
"\(name):\(item)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedProperty: Bird = new { // <1>
|
||||
typedProperty: Bird = new { // <2>
|
||||
name = "Swift"
|
||||
}
|
||||
|
||||
untypedProperty = new { // <2>
|
||||
untypedProperty = new { // <3>
|
||||
hello = "world"
|
||||
}
|
||||
|
||||
typedListing: Listing<Bird> = new {
|
||||
new { // <3>
|
||||
new { // <4>
|
||||
name = "Kite"
|
||||
}
|
||||
}
|
||||
|
||||
untypedListing: Listing = new {
|
||||
new { // <4>
|
||||
new { // <5>
|
||||
hello = "there"
|
||||
}
|
||||
}
|
||||
@@ -3413,13 +3416,13 @@ typedMapping: Mapping<String, Bird> = new {
|
||||
default { entryKey ->
|
||||
name = entryKey
|
||||
}
|
||||
["Saltmarsh Sparrow"] = new { // <5>
|
||||
["Saltmarsh Sparrow"] = new { // <6>
|
||||
name = "Sharp-tailed Sparrow"
|
||||
}
|
||||
}
|
||||
|
||||
amendedMapping = (typedMapping) {
|
||||
["Saltmarsh Sparrow"] = new {} // <6>
|
||||
["Saltmarsh Sparrow"] = new {} // <7>
|
||||
}
|
||||
|
||||
class Aviary {
|
||||
@@ -3429,22 +3432,27 @@ class Aviary {
|
||||
}
|
||||
|
||||
aviary: Aviary = new {
|
||||
birds = new { // <7>
|
||||
birds = new { // <8>
|
||||
new { name = "Kiwi" }
|
||||
}
|
||||
}
|
||||
|
||||
swiftHatchlings = typedProperty.listHatchlings(new { "Poppy"; "Chirpy" }) // <8>
|
||||
----
|
||||
swiftHatchlings = typedProperty.listHatchlings(new { "Poppy"; "Chirpy" }) // <9>
|
||||
|
||||
<1> Assignment to a property with an explicitly declared type, amending `new Bird {}`.
|
||||
<2> Assignment to an undeclared property in module context, amending `new Dynamic {}`.
|
||||
<3> `Listing` element creation, amending implicit `default`, `new Bird {}`.
|
||||
<4> `Listing` element creation, amending implicit `default`, `new Dynamic {}`.
|
||||
<5> `Mapping` value assignment, amending the result of applying `default` to `"Saltmarsh Sparrow"`, `new Bird { name = "Saltmarsh Sparrow" }`.
|
||||
<6> `Mapping` value assignment _replacing_ the parent's entry, amending the result of applying `default` to `"Saltmarsh Sparrow"`, `new Bird { name = "Saltmarsh Sparrow" }`.
|
||||
<7> Amending the property default value `new Listing { new Bird { name = "Osprey" } }`; the result contains both birds.
|
||||
<8> Error: Cannot tell which parent to amend.
|
||||
pigeonHatchlings =
|
||||
let (hatchlingNames: Listing<String> = new { "Polly"; "Daisy" }) // <10>
|
||||
new Bird { name = "Pigeon" }.listHatchlings(hatchlingNames)
|
||||
----
|
||||
<1> Instantiation of a method return value, amending the return type's default value `new Listing<String> {}`.
|
||||
<2> Assignment to a property with an explicitly declared type, amending `new Bird {}`.
|
||||
<3> Assignment to an undeclared property in module context, amending `new Dynamic {}`.
|
||||
<4> `Listing` element creation, amending implicit `default`, `new Bird {}`.
|
||||
<5> `Listing` element creation, amending implicit `default`, `new Dynamic {}`.
|
||||
<6> `Mapping` value assignment, amending the result of applying `default` to `"Saltmarsh Sparrow"`, `new Bird { name = "Saltmarsh Sparrow" }`.
|
||||
<7> `Mapping` value assignment _replacing_ the parent's entry, amending the result of applying `default` to `"Saltmarsh Sparrow"`, `new Bird { name = "Saltmarsh Sparrow" }`.
|
||||
<8> Amending the property default value `new Listing { new Bird { name = "Osprey" } }`; the result contains both birds.
|
||||
<9> Instantiation of a method argument, amending the parameter type's default value `new Listing<String> {}`.
|
||||
<10> Instantiation inside a <<let-expressions,`let` binding>>, amending the binding's type's default value `new Listing<String> {}`.
|
||||
|
||||
[[let-expressions]]
|
||||
=== Let Expressions
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
= Pkl 0.33 Release Notes
|
||||
:version: 0.33
|
||||
:version-minor: 0.33.0
|
||||
:release-date: XXX
|
||||
:release-date: November 5th, 2026
|
||||
:version-next: 0.34
|
||||
:version-next-date: February 2027
|
||||
|
||||
@@ -9,12 +9,56 @@ include::partial$intro.adoc[]
|
||||
|
||||
== Highlights [small]#💖#
|
||||
|
||||
[[generic-methods]]
|
||||
=== Generic Methods
|
||||
|
||||
Support for generic methods has been greatly expanded (https://github.com/apple/pkl/pull/1849[#1849], https://github.com/apple/pkl/pull/1940[#1940]).
|
||||
|
||||
A generic method is a method that accepts types as arguments.
|
||||
This is a powerful tool that allows writing business logic that works over a variety of types.
|
||||
|
||||
For example, this code declares two parameters: type parameter `T`, and value parameter `arg`.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
function identity<T>(arg: T): T = arg
|
||||
----
|
||||
|
||||
Generic methods currently already exist in a limited sense:
|
||||
|
||||
. Only the standard library can declare generic methods.
|
||||
. It is not possible to pass in type arguments when calling generic methods.
|
||||
|
||||
In Pkl 0.33, both of these restrictions are lifted.
|
||||
|
||||
To pass type arguments into a generic method, add the type surrounded by angle brackets:
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
result = identity<String>("Hello, World!")
|
||||
----
|
||||
|
||||
If type arguments are omitted entirely, it behaves as calling the method with the `unknown` type.
|
||||
The following two are logically identical:
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
result = identity("Hello, World!")
|
||||
result2 = identity<unknown>("Hello, World!")
|
||||
----
|
||||
|
||||
This is a <<parser-rule-change-for-comparison,breaking change>>: in some cases, code that parses as a comparison expression now parses as a method call.
|
||||
|
||||
To read more about generic methods, consult the xref:language-reference:index.adoc#generic-methods[language reference].
|
||||
|
||||
To learn more about the design of generic method calls, consult https://github.com/apple/pkl-evolution/blob/main/spices/SPICE-0032-generic-methods.adoc[SPICE-0032].
|
||||
|
||||
=== New standard library module: `pkl:net`
|
||||
|
||||
This release introduces a new standard library module, link:{uri-stdlib-netModule}[`pkl:net`], which brings native URL support to Pkl (https://github.com/apple/pkl/pull/1834[#1834]).
|
||||
A new standard library module is introduced called pkldoc:#[pkl:net], for working with network types (https://github.com/apple/pkl/pull/1834[#1834]).
|
||||
|
||||
Its centerpiece is link:{uri-stdlib-net-Url}[`net.Url`], a URL as defined by https://www.rfc-editor.org/rfc/rfc3986[RFC 3986].
|
||||
A string is parsed with `net.Url()`, which accepts an absolute URL as well as a relative reference, and which throws if the string cannot be parsed:
|
||||
Its centerpiece is pkldoc:Url[pkl:net], a URL as defined by https://www.rfc-editor.org/rfc/rfc3986[RFC 3986].
|
||||
A string is parsed with pkldoc:Url()[pkl:net], which accepts an absolute URL as well as a relative reference, and which throws if the string cannot be parsed:
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
@@ -75,16 +119,192 @@ To instead compare them as the *syntax-based normalization* of RFC 3986, where s
|
||||
same = net.Url("HTTPS://Example.com/%7Euser").equals(net.Url("https://example.com/~user")) // true
|
||||
----
|
||||
|
||||
The module also provides standalone helpers: `net.encodeUrlComponent()` and `net.decodeUrlComponent()` for percent-encoding, and `net.buildQuery()` and `net.parseQuery()` for `application/x-www-form-urlencoded` queries.
|
||||
The module also provides standalone helpers: pkldoc:encodeUrlComponent()[pkl:net] and pkldoc:decodeUrlComponent()[pkl:net] for percent-encoding, and pkldoc:buildQuery()[pkl:net] and pkldoc:parseQuery()[pkl:net] for `application/x-www-form-urlencoded` queries.
|
||||
|
||||
Alongside this module, `pkl:base` gains link:{uri-stdlib-String}#isValidUrl[`String.isValidUrl`], which tells whether a string is a valid absolute URL.
|
||||
Alongside this module, `pkl:base` gains pkldoc:String#isValidUrl[], which tells whether a string is a valid absolute URL.
|
||||
It is stricter than `net.Url()`, which also parses a relative reference, and which percent-encodes whatever cannot appear literally in a URL component.
|
||||
The `Uri` typealias is now defined in terms of it, which is a <<uri-validates,breaking change>>.
|
||||
|
||||
=== New standard library module: `pkl:syntax`
|
||||
|
||||
A new standard library module is introduced called pkldoc:#[pkl:syntax], for working with Pkl source code (https://github.com/apple/pkl/pull/1821[#1821], https://github.com/apple/pkl/pull/1964[#1964], https://github.com/apple/pkl/pull/1955[#1955]).
|
||||
|
||||
It has three parts:
|
||||
|
||||
* pkldoc:Parser[pkl:syntax] parses a string or resource into a syntax tree, as either a module or an expression.
|
||||
* pkldoc:Node[pkl:syntax] is a node of that tree.
|
||||
It has a `type`, `children`, the verbatim source `text`, and the source `span`.
|
||||
Nodes can be searched, folded, and replaced with the `find*`, `fold`, and `replace*` methods.
|
||||
* pkldoc:FormattingRenderer[pkl:syntax] renders a tree back to Pkl source code, using the canonical Pkl formatter.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
import "pkl:syntax"
|
||||
|
||||
local myModule = new syntax.Parser {}.parseModule("""
|
||||
class Point {
|
||||
x: Int
|
||||
y: Int
|
||||
}
|
||||
""")
|
||||
|
||||
className = myModule.findChild((n) -> n.type == "class").findChildOfType("identifier").text // "Point"
|
||||
|
||||
ifCount = myModule.fold(0, (acc, n) -> if (n.type == "if_expr") acc + 1 else acc) // 0
|
||||
----
|
||||
|
||||
=== C Library (libpkl)
|
||||
|
||||
A new C library, libpkl, is introduced (https://github.com/apple/pkl/pull/1238[#1238], https://github.com/apple/pkl/pull/1799[#1799], https://github.com/apple/pkl/pull/1801[#1801], https://github.com/apple/pkl/pull/1805[#1805], https://github.com/apple/pkl/pull/1812[#1812]).
|
||||
|
||||
One of Pkl's selling points is the ability to embed the language into another runtime as a library.
|
||||
However, currently, callers from non-JVM languages must spawn Pkl as a child process.
|
||||
This introduces a system dependency on downstream users, and also introduces complexity and overhead for the operating system.
|
||||
|
||||
To address this pain point, a new library called libpkl is released for the C language.
|
||||
|
||||
This is a low-level library meant to be called into from language binding libraries.
|
||||
It exposes the xref:bindings-specification:message-passing-api.adoc[message passing API] through a small C interface (`pkl.h`).
|
||||
|
||||
Archives containing the header, both static and dynamic (shared) libraries, and `pkg-config` files are published for each supported OS and architecture, as part of the GitHub release.
|
||||
|
||||
To read more about libpkl, consult the xref:libpkl:index.adoc[libpkl documentation].
|
||||
|
||||
To read more about the design of this feature, consult https://github.com/apple/pkl-evolution/blob/main/spices/SPICE-0015-c-library-for-pkl.adoc[SPICE-0015].
|
||||
|
||||
Thank you to https://github.com/KushalP[@KushalP] for their contributions to this feature!
|
||||
|
||||
=== CPU Profiler
|
||||
|
||||
The Pkl CLI can now profile where an evaluation spends its CPU time (https://github.com/apple/pkl/pull/1823[#1823], https://github.com/apple/pkl/pull/1931[#1931]).
|
||||
|
||||
Profiling is enabled by passing `--profile-cpu-output`, which sets the file to write the profile to.
|
||||
The profile is written in https://github.com/google/pprof[pprof] format, so it can be explored with any tool that reads it, such as `go tool pprof`.
|
||||
|
||||
[source,shell,opts=novalidate]
|
||||
----
|
||||
$ pkl eval --profile-cpu-output profile.pb.gz myConfig.pkl
|
||||
$ go tool pprof -http=:8080 profile.pb.gz
|
||||
----
|
||||
|
||||
Profiling is only exposed through the CLI.
|
||||
For more details, consult xref:pkl-cli:index.adoc#profile-cpu-output[the CLI documentation].
|
||||
|
||||
== Noteworthy [small]#🎶#
|
||||
|
||||
=== `this` as a type
|
||||
|
||||
The `this` keyword can now be used as a type (https://github.com/apple/pkl/pull/1708[#1708], https://github.com/apple/pkl/pull/1962[#1962]).
|
||||
|
||||
A self type is the type of the object that a member is accessed on.
|
||||
Self types are useful when building class hierarchies, because they let a member refer to the _same_ type as the object it belongs to, even after the class is extended.
|
||||
|
||||
Currently, Pkl has a self-type, `module`, but it specifically describes the type of the module object.
|
||||
There is no equivalent for regular classes nor objects.
|
||||
|
||||
To address this shortcoming, the `this` keyword is now also a type.
|
||||
It refers to the self-type of the directly enclosing object, class, or module.
|
||||
|
||||
When a class is extended, `this` in an inherited member refers to the subclass, not to the class that declares the member:
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
open class Node {
|
||||
parent: this?
|
||||
children: List<this>
|
||||
}
|
||||
|
||||
class SpecialNode extends Node {
|
||||
special: Boolean
|
||||
}
|
||||
|
||||
node: SpecialNode = new {
|
||||
special = true
|
||||
parent = new SpecialNode { special = false; children = List() } // <1>
|
||||
children = List(new SpecialNode { special = true; children = List() })
|
||||
}
|
||||
|
||||
bad: SpecialNode = new {
|
||||
special = true
|
||||
parent = new Node {} // <2>
|
||||
}
|
||||
----
|
||||
<1> `parent` has type `SpecialNode?`.
|
||||
<2> Error: `Node` is not a `SpecialNode`.
|
||||
|
||||
The `this` type can be used in properties, method parameters and return types, function types, and type arguments.
|
||||
It cannot be used in a type alias body.
|
||||
|
||||
The `this` type has also been <<this-adoption,adopted in the standard library>>.
|
||||
|
||||
To read more about the design, see https://github.com/apple/pkl-evolution/blob/main/spices/SPICE-0029-self-type.adoc[SPICE-0029].
|
||||
|
||||
=== Better `new {}` inference
|
||||
|
||||
The `new {}` expression can now correctly infer its parent in more positions (https://github.com/apple/pkl/pull/1768[#1768], https://github.com/apple/pkl/pull/1824[#1824], https://github.com/apple/pkl/pull/1845[#1845], https://github.com/apple/pkl/pull/1847[#1847], https://github.com/apple/pkl/pull/1857[#1857]).
|
||||
|
||||
An xref:language-reference:index.adoc#implicitly-typed-new[implicitly typed `new {}` expression] tells Pkl to infer the parent when amending.
|
||||
When used inside a property, for example, it amends the class property default.
|
||||
|
||||
Using `new {}` in the following positions currently throw, and will work in Pkl 0.33:
|
||||
|
||||
* Method arguments
|
||||
* Let bindings
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
class Bird {
|
||||
name: String
|
||||
}
|
||||
|
||||
function greet(bird: Bird): String = "Hello, \(bird.name)"
|
||||
|
||||
greeting1 = greet(new { name = "Pigeon" }) // <1>
|
||||
|
||||
greeting2 =
|
||||
let (bird: Bird = new { name = "Parrot" }) // <2>
|
||||
greet(bird)
|
||||
----
|
||||
<1> The argument is inferred to be a `Bird`.
|
||||
<2> The `let` binding is inferred to be a `Bird`.
|
||||
|
||||
Inference is not available where the parameter type is not known ahead of time.
|
||||
Additionally, it cannot be used for constructor methods like `List()`, generic methods like `Pair()`, and `Function.apply()`.
|
||||
|
||||
It is an error for the parameter type to be `this` or `module`.
|
||||
|
||||
=== Support for parsing `.netrc` files into HTTP headers
|
||||
|
||||
Pkl now supports parsing `.netrc` files to configure HTTP Basic authentication headers (https://github.com/apple/pkl/pull/1817[#1817], https://github.com/apple/pkl/pull/1854[#1854]).
|
||||
|
||||
A new method is introduced called `netRcHeaders()` on class `pkl.EvaluatorSettings#Http`.
|
||||
|
||||
It can be used to read credentials directly from a local `.netrc` file and mapped to HTTP `Authorization` headers:
|
||||
|
||||
.~/.config/pkl/settings.pkl
|
||||
[source,pkl]
|
||||
----
|
||||
amends "pkl:settings"
|
||||
|
||||
http {
|
||||
headers = netRcHeaders(read("/Users/johnappleseed/.netrc"))
|
||||
}
|
||||
----
|
||||
|
||||
It follows standard `curl` parsing rules, supporting comments, quoted values, and escaped characters.
|
||||
|
||||
Thank you to https://github.com/ayashjorden[@ayashjorden] for their contributions to this feature!
|
||||
|
||||
=== CLI Changes
|
||||
|
||||
==== Package installation to the local cache
|
||||
|
||||
The `pkl project package` command has gained a new `--install` flag that triggers installation of the built package(s) into the module cache (https://github.com/apple/pkl/pull/1795[#1795]).
|
||||
|
||||
Local cache installation is useful for local end-to-end testing of dependency trees.
|
||||
This functionality is also available via pkl-gradle.
|
||||
|
||||
|
||||
==== Default file locations
|
||||
|
||||
For new setups, the CLI no longer stores anything under `~/.pkl` (https://github.com/apple/pkl/pull/1809[#1809]).
|
||||
@@ -121,13 +341,17 @@ For example, setting `XDG_CACHE_HOME` will configure the cache directory.
|
||||
|
||||
Note that the existing `~/.pkl/cache` directory is ignored, so Pkl will download packages to populate its cache if configured to do so.
|
||||
|
||||
To learn more about this design, consult https://github.com/apple/pkl-evolution/blob/main/spices/SPICE-0031-os-base-directories.adoc[SPICE-0031].
|
||||
|
||||
Thank you to https://github.com/florinungur[@florinungur] for their contributions to this feature!
|
||||
|
||||
=== Java Library Changes
|
||||
|
||||
==== `pkl.net#Url` maps to `java.net.URI`
|
||||
|
||||
The JVM bindings now understand the new `pkl.net#Url` class (https://github.com/apple/pkl/pull/1834[#1834]).
|
||||
|
||||
The Java and Kotlin code generators generate a `java.net.URI` for a property whose type is `net.Url`.
|
||||
The Java and Kotlin code generators generate a `java.net.URI` for a property whose type is pkldoc:Url[pkl:net].
|
||||
|
||||
Two conversions are added to `org.pkl.config.java.mapper.Conversions`, both part of the preconfigured set:
|
||||
|
||||
@@ -140,33 +364,71 @@ Two conversions are added to `org.pkl.config.java.mapper.Conversions`, both part
|
||||
|
||||
* New module introduced.
|
||||
|
||||
==== `pkl:syntax`
|
||||
|
||||
* New module introduced.
|
||||
|
||||
==== `pkl:base`
|
||||
|
||||
* New property: link:{uri-stdlib-String}#isValidUrl[`String.isValidUrl`]
|
||||
* Changed typealias: link:{uri-stdlib-Uri}[`Uri`] is now `String(isValidUrl)` (<<uri-validates,breaking change>>)
|
||||
* New property: pkldoc:String#isValidUrl[]
|
||||
* Changed typealias: pkldoc:Uri[] is now `String(isValidUrl)` (<<uri-validates,breaking change>>)
|
||||
* [[this-adoption]] Properties refined with `this` type
|
||||
** pkldoc:Any.getClass()[] now returns `Class<this>`
|
||||
** pkldoc:Any.ifNonNull()[] now accepts an argument of type `(this) \-> Result`
|
||||
|
||||
==== `pkl:ref`
|
||||
|
||||
* Renamed class: `Domain` is now `AbstractDomain` (<<reference-changes,breaking change>>)
|
||||
* Changed method: `Reference()` now takes type arguments instead of a `Class` parameter (<<reference-changes,breaking change>>)
|
||||
* pkldoc:AbstractDomain.renderReference()[pkl:ref] now accepts a `Reference<this, Any>`
|
||||
* No longer considered experimental.
|
||||
|
||||
==== `pkl:protobuf`
|
||||
|
||||
* Module deprecated for removal in Pkl 0.34 (https://github.com/apple/pkl/pull/1778[#1778]).
|
||||
|
||||
== Breaking Changes [small]#💔#
|
||||
|
||||
=== Removal of macOS amd64 (Intel) Binaries
|
||||
|
||||
Native `pkl` and `pkldoc` binaries for Intel Mac systems are no longer published with Pkl releases.
|
||||
Native `pkl` and `pkldoc` binaries for Intel Mac systems are no longer published with Pkl releases (https://github.com/apple/pkl/pull/1769[#1769]).
|
||||
|
||||
To continue running new Pkl releases on these systems, use an appropriate Java runtime and the `jpkl` and `jpkldoc` Java executables.
|
||||
|
||||
=== Type check changes for `Class<T>`
|
||||
|
||||
In prior versions of Pkl, type arguments to the `Class` type were erased.
|
||||
Currently, type arguments to the `Class` type are erased.
|
||||
Any `Class` value would typecheck against `Class<T>` for any value of `T`.
|
||||
|
||||
In Pkl 0.33, this erasure has been removed.
|
||||
A `Class` value typechecked against `Class<T>` must be a subclass of `T`.
|
||||
A `Class` value typechecked against `Class<T>` must be a subclass of `T` (https://github.com/apple/pkl/pull/1698[#1698]).
|
||||
|
||||
If `T` does not resolve to a class type (i.e. it is a union type, nullable type, string literal type, parameterized type, or `nothing`), the type check will always fail.
|
||||
|
||||
=== Standard library `external` module properties are now marked `const`
|
||||
=== Standard library properties marked `const`
|
||||
|
||||
Previously, module properties in `pkl:math` and `pkl:release` could be overriden by amending the module.
|
||||
Doing this makes little sense—these value are constants and overriding them by amending their module would be odd.
|
||||
Some properties within the `pkl:math` and `pkl:release` modules have been marked `const` (https://github.com/apple/pkl/pull/1864[#1864]).
|
||||
|
||||
Currently, module properties in `pkl:math` and `pkl:release` can be overridden by amending the module.
|
||||
Doing this makes little sense; these values are constants and overriding them by amending their module would be odd.
|
||||
|
||||
The following properties are now `const` and cannot be amended:
|
||||
|
||||
* pkldoc:minInt[pkl:math]
|
||||
* pkldoc:maxInt[pkl:math]
|
||||
* pkldoc:maxInt8[pkl:math]
|
||||
* pkldoc:maxInt16[pkl:math]
|
||||
* pkldoc:maxInt32[pkl:math]
|
||||
* pkldoc:maxUInt[pkl:math]
|
||||
* pkldoc:maxUInt8[pkl:math]
|
||||
* pkldoc:maxUInt16[pkl:math]
|
||||
* pkldoc:maxUInt32[pkl:math]
|
||||
* pkldoc:minFiniteFloat[pkl:math]
|
||||
* pkldoc:maxFiniteFloat[pkl:math]
|
||||
* pkldoc:minPositiveFloat[pkl:math]
|
||||
* pkldoc:e[pkl:math]
|
||||
* pkldoc:pi[pkl:math]
|
||||
* pkldoc:current[pkl:release]
|
||||
|
||||
This is a breaking change for code that looks like this:
|
||||
[source,pkl]
|
||||
@@ -223,7 +485,7 @@ res = """
|
||||
[[uri-validates]]
|
||||
=== `Uri` validates its value
|
||||
|
||||
The link:{uri-stdlib-Uri}[`Uri`] typealias in `pkl:base` is now `String(isValidUrl)` instead of a plain `String` (https://github.com/apple/pkl/pull/1834[#1834]).
|
||||
The pkldoc:Uri[] typealias in `pkl:base` is now `String(isValidUrl)` instead of a plain `String` (https://github.com/apple/pkl/pull/1834[#1834]).
|
||||
|
||||
A value typed as `Uri` must be a valid absolute URL according to https://www.rfc-editor.org/rfc/rfc3986[RFC 3986].
|
||||
This means that a relative reference, or a URL containing a character that must be percent-encoded, no longer type-checks:
|
||||
@@ -236,16 +498,241 @@ bad1: Uri = "./some/path" // throws: not absolute
|
||||
bad2: Uri = "https://example.com/some path" // throws: space must be percent-encoded
|
||||
----
|
||||
|
||||
This affects every standard library member typed as `Uri`, among them link:{uri-stdlib-Resource}#uri[`Resource.uri`], link:{uri-stdlib-analyzeModule}#importGraph()[`analyze.importGraph()`], and the URI-valued properties of `pkl:Project`, `pkl:EvaluatorSettings` and `pkl:DocPackageInfo`.
|
||||
This affects every standard library member typed as `Uri`, among them pkldoc:Resource#uri[], pkldoc:importGraph()[pkl:analyze], and the URI-valued properties of pkldoc:#[pkl:Project], pkldoc:#[pkl:EvaluatorSettings] and pkldoc:#[pkl:DocPackageInfo].
|
||||
|
||||
As a consequence, an invalid URI is now reported as a type constraint violation at the point where it is set, rather than as an error raised later by whatever consumes it.
|
||||
|
||||
[[reference-changes]]
|
||||
=== Changes to `Reference` construction
|
||||
|
||||
As part of the introduction of generic methods, the `Reference()` constructor method in `pkl:ref` takes the domain and referent types as type arguments instead of taking a `Class` parameter (https://github.com/apple/pkl/pull/1849[#1849]).
|
||||
This also makes it possible to construct references to non-class types, such as `Listing<String>` or `String | Int`.
|
||||
|
||||
The `ref.Domain` class has been renamed to `ref.AbstractDomain`.
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
import "pkl:ref"
|
||||
|
||||
class MyDomain extends ref.AbstractDomain { // <1>
|
||||
function renderReference(reference: ref.Reference<MyDomain, Any>): String = "..."
|
||||
}
|
||||
|
||||
// current
|
||||
myRef = ref.Reference(new MyDomain {}, MyReferent, myData)
|
||||
|
||||
// new
|
||||
myRef = ref.Reference<MyDomain, MyReferent>(new MyDomain {}, myData) // <2>
|
||||
----
|
||||
<1> In Pkl 0.32, `extends ref.Domain`.
|
||||
<2> Constraints in the referent type of a `Reference` type annotation are no longer an error, they are ignored.
|
||||
|
||||
[#parser-rule-change-for-comparison]
|
||||
=== Parser rule changes for comparison
|
||||
|
||||
To support <<generic-methods,generic method calls>>, the syntax for Pkl has changed to permit passing type arguments when calling a method.
|
||||
|
||||
This purposefully introduces an ambiguity to the grammar: the following expression can be parsed as either a generic method call, or as nested comparison expressions:
|
||||
|
||||
[source,{pkl-expr}]
|
||||
----
|
||||
foo < Int > (5)
|
||||
----
|
||||
|
||||
To resolve such ambiguities, such code is preferably parsed as a generic method call.
|
||||
|
||||
This contrived example is nonsensical today, because it is an error to compare a boolean.
|
||||
However, there are times when such code might be written in a well-formed way, for example:
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
res = foo(
|
||||
bar < baz,
|
||||
qux > (corge + 3)
|
||||
)
|
||||
----
|
||||
|
||||
In Pkl 0.33, this above snippet will interpret `bar` as a generic method call.
|
||||
To restore the old meaning, wrap the left-hand side with parentheses:
|
||||
|
||||
[source,diff]
|
||||
----
|
||||
res = foo(
|
||||
- bar < baz,
|
||||
+ (bar) < baz,
|
||||
qux > (corge + 3)
|
||||
)
|
||||
----
|
||||
|
||||
=== `test.catch()` and `test.catchOrNull()` force their result
|
||||
|
||||
The pkldoc:catch()[pkl:test] and pkldoc:catchOrNull()[pkl:test] methods now fully evaluate the value returned by the function they are given (https://github.com/apple/pkl/pull/1910[#1910]).
|
||||
|
||||
Currently, an error nested inside the returned value was not caught.
|
||||
It surfaced later, when the value was used.
|
||||
In Pkl 0.33, it is caught, and `catch()` returns its message.
|
||||
|
||||
=== Abstract methods must be implemented in extending non-abstract classes/modules
|
||||
|
||||
When extending an abstract class or module, it is now an error if any abstract methods are not implemented.
|
||||
|
||||
In the following snippet, class `Swallow` is invalid because it does not implement `canCarry`:
|
||||
|
||||
[source,pkl]
|
||||
----
|
||||
abstract class Bird {
|
||||
abstract function canCarry(fruit: Fruit): Boolean
|
||||
}
|
||||
|
||||
class Swallow extends Bird {
|
||||
type: "European" | "African"
|
||||
}
|
||||
----
|
||||
|
||||
=== Removal of `module` type in const scopes
|
||||
|
||||
The `module` type should no longer be used inside typealiases, class bodies, annotation bodies, and `const` scopes.
|
||||
Such usages will emit a deprecation warning, and will become a full error in Pkl 0.34 (https://github.com/apple/pkl/pull/1708[#1708]).
|
||||
|
||||
The `module` type is a self-type, which refers to the `this` of the module.
|
||||
When a module is extended, the `module` type refers to the extending module.
|
||||
On the other hand, the definition of classes and typealiases cannot be changed by an extending module.
|
||||
|
||||
The following snippet is misleading, because the module property `friend` _is_ a self-type, whereas class property `Feature.animal` is not.
|
||||
|
||||
.Bird.pkl
|
||||
[source,pkl]
|
||||
----
|
||||
open module Bird
|
||||
|
||||
friend: module? // <1>
|
||||
|
||||
class Feature {
|
||||
animal: module? // <2>
|
||||
}
|
||||
----
|
||||
<1> Self-type
|
||||
<2> Not a self-type
|
||||
|
||||
To have clearer semantics, the `module` type can no longer be used inside const scopes.
|
||||
|
||||
In most cases, such code should be replaced with a self-import.
|
||||
|
||||
.Bird.pkl
|
||||
[source,pkl]
|
||||
----
|
||||
open module Bird
|
||||
|
||||
import "Bird.pkl" // <1>
|
||||
|
||||
class Feature {
|
||||
animal: Bird // <2>
|
||||
}
|
||||
----
|
||||
<1> Self-import to use `Bird` as a type
|
||||
|
||||
=== Protobuf module deprecated
|
||||
|
||||
The `pkl:protobuf` module is deprecated without replacement (https://github.com/apple/pkl/pull/1778[#1778]).
|
||||
|
||||
The protobuf module renders Pkl data into the "textproto" format.
|
||||
However, Pkl is more expressive than protobuf, which means that Pkl's renderer needs to make rendering choices that are bespoke to Pkl's protobuf renderer.
|
||||
|
||||
For example, there is no native equivalent for Pkl's `null` literal.
|
||||
To address this, Pkl's protobuf renderer renders these as a "null" scalar.
|
||||
|
||||
These rendering choices are somewhat ad-hoc and likely to break from one usage to the next.
|
||||
|
||||
Users of protobuf are encouraged render Pkl into https://protobuf.dev/programming-guides/json/[ProtoJSON] instead.
|
||||
|
||||
== Miscellaneous [small]#🐸#
|
||||
|
||||
* The `abstract` modifier is now a no-op for properties. (https://github.com/apple/pkl/pull/1781[#1781]).
|
||||
* Abstract methods in non-abstract classes and modules are now rejected (https://github.com/apple/pkl/pull/1647[#1647], https://github.com/apple/pkl/pull/1780[#1780]).
|
||||
* Enforce that non-abstract classes implement all abstract methods from superclasses (https://github.com/apple/pkl/pull/1785[#1785]).
|
||||
* Introduce a new internal representation for type metadata (https://github.com/apple/pkl/pull/1838[#1838]).
|
||||
* Improve error message when amending a property with no value set (https://github.com/apple/pkl/pull/1867[#1867]).
|
||||
* Use `EnumSet` for token categories (https://github.com/apple/pkl/pull/1803[#1803]).
|
||||
* pkldoc:String.toInt()[] now supports all hexadecimal, octal, and binary formats (https://github.com/apple/pkl/pull/1808[#1808]).
|
||||
* Handle conditional pluralization in error message (https://github.com/apple/pkl/pull/1848[#1848]).
|
||||
* Avoid using Java `Object.toString()` to present language-facing string representations (https://github.com/apple/pkl/pull/1850[#1850]).
|
||||
* Unify internal construction of objects (https://github.com/apple/pkl/pull/1873[#1873]).
|
||||
* Use module cache directory configured via the CLI or Gradle while evaluating `PklProject` and `settings.pkl` files (https://github.com/apple/pkl/pull/1900[#1900]).
|
||||
* Typed values are rendered with more helpful type names in error messages and pkldoc:Any.toString()[] (https://github.com/apple/pkl/pull/1412[#1412]).
|
||||
* Add support for customizing spring boot `@ConfigurationProperties` in generated Java/Kotlin code (https://github.com/apple/pkl/pull/1897[#1897]).
|
||||
* Improve error message when instantiating a class that cannot be instantiated (https://github.com/apple/pkl/pull/1916[#1916]).
|
||||
* Improve error messages when a type alias fails to type check (https://github.com/apple/pkl/pull/1914[#1914]).
|
||||
* Add descriptions and groups to the tasks created by the pkl-gradle plugin (https://github.com/apple/pkl/pull/190[#190]).
|
||||
* Pkldoc no longer truncates the names of modules that do not start with the package's module name prefix (https://github.com/apple/pkl/pull/1909[#1909]).
|
||||
* Reject `file:` URIs that include an authority (https://github.com/apple/pkl/pull/629[#629]).
|
||||
* Upgrade to GraalVM 25.2.4 (https://github.com/apple/pkl/pull/1804[#1804]).
|
||||
* Improve performance of reading `const` members (https://github.com/apple/pkl/pull/1835[#1835]).
|
||||
* Improve performance of `Listing` and `Mapping` type casts (https://github.com/apple/pkl/pull/1837[#1837]).
|
||||
* Improve performance of lexical frame resolution (https://github.com/apple/pkl/pull/1842[#1842]).
|
||||
* Improve performance of amending `null` parents (https://github.com/apple/pkl/pull/1836[#1836]).
|
||||
* Improve performance of annotations without object bodies (https://github.com/apple/pkl/pull/1843[#1843]).
|
||||
* Improve performance of `for` and `when` generators (https://github.com/apple/pkl/pull/1844[#1844]).
|
||||
* Improve performance of parent property and subscript access (https://github.com/apple/pkl/pull/1853[#1853]).
|
||||
* Improve performance of typechecking (https://github.com/apple/pkl/pull/1871[#1871]).
|
||||
* Improve performance of string literal union types in more cases (https://github.com/apple/pkl/pull/1875[#1875]).
|
||||
* Improve performance of iterating object members (https://github.com/apple/pkl/pull/1879[#1879]). Thank you to https://github.com/odenix[@odenix] for their contributions to this feature!
|
||||
* Fix some partial evaluation issues in the GraalVM compiler (https://github.com/apple/pkl/pull/1944[#1944]).
|
||||
|
||||
== Bug Fixes [small]#🐜#
|
||||
|
||||
* XXX
|
||||
* Fix incorrect behavior when objects are partially forced (https://github.com/apple/pkl/pull/1790[#1790]).
|
||||
* Fix issues publishing pkl-gradle (https://github.com/apple/pkl/pull/1777[#1777], https://github.com/apple/pkl/pull/1807[#1807]).
|
||||
* Fix resolution of the `module` type in typealias bodies (https://github.com/apple/pkl/pull/1796[#1796]).
|
||||
* Don't fail when loading known-malformed CA certs (https://github.com/apple/pkl/pull/1806[#1806]).
|
||||
* Fix resolution of type names in typealias constraints (https://github.com/apple/pkl/pull/1826[#1826]).
|
||||
* Fix parsing of block comments at the end of a file (https://github.com/apple/pkl/pull/1828[#1828]).
|
||||
* Sanitize block comment endings in generated Kotlin doc comments (https://github.com/apple/pkl/pull/1830[#1830]).
|
||||
* Enforce max collection size when decoding pkl-binary data (https://github.com/apple/pkl/pull/1831[#1831]).
|
||||
* Correctly omit glob imports from reflected imports (https://github.com/apple/pkl/pull/1816[#1816]).
|
||||
* Escape characters that cannot appear literally in rendered YAML (https://github.com/apple/pkl/pull/1846[#1846]).
|
||||
* Fix invalid prefix when generating spring boot config (https://github.com/apple/pkl/pull/1862[#1862]).
|
||||
* Fix `pkl run` behaviors where (sub)commands amend `pkl:Command` without extending it (https://github.com/apple/pkl/pull/1882[#1882]).
|
||||
* Fix pkldoc:String.endsWith()[] for overlapping regex matches (https://github.com/apple/pkl/pull/1880[#1880], https://github.com/apple/pkl/pull/1884[#1884]).
|
||||
* Fix leak of external reader processes in the language binding server (https://github.com/apple/pkl/pull/1885[#1885]).
|
||||
* Fix decoding of `Regex` values from pkl-binary data (https://github.com/apple/pkl/pull/1895[#1895]).
|
||||
* Fix `pkl eval` of dependency notation source modules when using multiple file output (https://github.com/apple/pkl/pull/1942[#1942]).
|
||||
* Report an error, instead of overflowing the stack, when parsing or formatting code that is nested too deeply (https://github.com/apple/pkl/pull/1918[#1918], https://github.com/apple/pkl/pull/1953[#1953]).
|
||||
* Fix type check of the `module` type when it is defined in a parent member body (https://github.com/apple/pkl/pull/1936[#1936]).
|
||||
* Fix type check of subscript key types for `Map` and `Mapping` references (https://github.com/apple/pkl/pull/1933[#1933]).
|
||||
* Fix `hashCode()` and `==` inconsistency for negative zero in `Duration` and `DataSize` (https://github.com/apple/pkl/pull/1932[#1932]).
|
||||
* Fix `hashCode()` inconsistency with `==` for `Listing`, `Duration`, and `DataSize` (https://github.com/apple/pkl/pull/1922[#1922]).
|
||||
* Fix `toString()` and `value` of `Duration` and `DataSize` values that are too large to fit in a `Long` (https://github.com/apple/pkl/pull/1935[#1935]).
|
||||
* Fix iteration over `Dynamic` objects that have a negative key, such as `new Dynamic { [-1] = 2 }` (https://github.com/apple/pkl/pull/1948[#1948]).
|
||||
* Fix enforcement of `const` member access inside methods (https://github.com/apple/pkl/pull/1945[#1945]).
|
||||
* Fix parameterized type checks in type alias constraints (https://github.com/apple/pkl/pull/1906[#1906]).
|
||||
* Fix resolution of qualified type names (https://github.com/apple/pkl/pull/1915[#1915]).
|
||||
* Fix lookaround regexes in pkldoc:String.lastIndexOf()[] and pkldoc:String.replaceLast()[] (https://github.com/apple/pkl/pull/1908[#1908]).
|
||||
* Fix formatter instability (https://github.com/apple/pkl/pull/1911[#1911]).
|
||||
* Improve normalization of URIs (https://github.com/apple/pkl/pull/1937[#1937], https://github.com/apple/pkl/pull/1954[#1954]).
|
||||
* Missing const checks which allow accessing non-const members (https://github.com/apple/pkl/issues/1963[#1963]).
|
||||
|
||||
== Contributors [small]#🙏#
|
||||
|
||||
We would like to thank the contributors to this release (in alphabetical order):
|
||||
|
||||
* XXX
|
||||
* https://github.com/AAGAM17[@AAGAM17]
|
||||
* https://github.com/aashish254[@aashish254]
|
||||
* https://github.com/ayashjorden[@ayashjorden]
|
||||
* https://github.com/bioball[@bioball]
|
||||
* https://github.com/Carpe-Wang[@Carpe-Wang]
|
||||
* https://github.com/dylanpulver[@dylanpulver]
|
||||
* https://github.com/florinungur[@florinungur]
|
||||
* https://github.com/goutamadwant[@goutamadwant]
|
||||
* https://github.com/henriquejsza[@henriquejsza]
|
||||
* https://github.com/HT154[@HT154]
|
||||
* https://github.com/KushalP[@KushalP]
|
||||
* https://github.com/kwy404[@kwy404]
|
||||
* https://github.com/mayc7n[@mayc7n]
|
||||
* https://github.com/netvl[@netvl]
|
||||
* https://github.com/odenix[@odenix]
|
||||
* https://github.com/protobufel2[@protobufel2]
|
||||
* https://github.com/RushikeshGandhmal[@RushikeshGandhmal]
|
||||
* https://github.com/sergiosalvi[@sergiosalvi]
|
||||
* https://github.com/sgammon[@sgammon]
|
||||
* https://github.com/stackoverflow[@stackoverflow]
|
||||
* https://github.com/vinayakj592[@vinayakj592]
|
||||
Reference in new issue
Block a user