diff --git a/docs/modules/language-reference/pages/index.adoc b/docs/modules/language-reference/pages/index.adoc index 5edf09fea..37062445e 100644 --- a/docs/modules/language-reference/pages/index.adoc +++ b/docs/modules/language-reference/pages/index.adoc @@ -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 (<>). 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): Listing = new { + function listHatchlings(items: Listing): Listing = 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 = new { - new { // <3> + new { // <4> name = "Kite" } } untypedListing: Listing = new { - new { // <4> + new { // <5> hello = "there" } } @@ -3413,13 +3416,13 @@ typedMapping: Mapping = 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 = 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 {}`. +<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 {}`. +<10> Instantiation inside a <>, amending the binding's type's default value `new Listing {}`. [[let-expressions]] === Let Expressions diff --git a/docs/modules/release-notes/pages/0.33.adoc b/docs/modules/release-notes/pages/0.33.adoc index fccfd1837..e988ac39a 100644 --- a/docs/modules/release-notes/pages/0.33.adoc +++ b/docs/modules/release-notes/pages/0.33.adoc @@ -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(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("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("Hello, World!") +---- + +This is a <>: 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 <>. +=== 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 +} + +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 <>. + +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)` (<>) +* New property: pkldoc:String#isValidUrl[] +* Changed typealias: pkldoc:Uri[] is now `String(isValidUrl)` (<>) +* [[this-adoption]] Properties refined with `this` type +** pkldoc:Any.getClass()[] now returns `Class` +** pkldoc:Any.ifNonNull()[] now accepts an argument of type `(this) \-> Result` + +==== `pkl:ref` + +* Renamed class: `Domain` is now `AbstractDomain` (<>) +* Changed method: `Reference()` now takes type arguments instead of a `Class` parameter (<>) +* pkldoc:AbstractDomain.renderReference()[pkl:ref] now accepts a `Reference` +* 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` -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` for any value of `T`. In Pkl 0.33, this erasure has been removed. -A `Class` value typechecked against `Class` must be a subclass of `T`. +A `Class` value typechecked against `Class` 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` 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): String = "..." +} + +// current +myRef = ref.Reference(new MyDomain {}, MyReferent, myData) + +// new +myRef = ref.Reference(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 <>, 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]