diff --git a/docs/modules/release-notes/pages/0.31.adoc b/docs/modules/release-notes/pages/0.31.adoc index 9be256b3..cb62260d 100644 --- a/docs/modules/release-notes/pages/0.31.adoc +++ b/docs/modules/release-notes/pages/0.31.adoc @@ -3,7 +3,7 @@ :version-minor: 0.XX.0 :release-date: TBD -link:ROOT:partial$component-attributes.adoc[role=include] +include::ROOT:partial$component-attributes.adoc[] Pkl {version} was released on {release-date}. + [.small]#The latest bugfix release is {version-minor}. (xref:changelog.adoc[All Versions])# @@ -26,7 +26,21 @@ News you don't want to miss. Ready when you need them. -=== XXX +=== Standard Library changes + +New properties have been added to the standard library (https://github.com/apple/pkl/pull/1396[#1396]). + +==== Additions to `pkl:base` + +The following APIs have been added: + +* link:{uri-stdlib-List}#isNotEmpty[`List.isNotEmpty`] +* link:{uri-stdlib-Map}#isNotEmpty[`Map.isNotEmpty`] +* link:{uri-stdlib-Set}#isNotEmpty[`Set.isNotEmpty`] +* link:{uri-stdlib-Listing}#isNotEmpty[`Listing.isNotEmpty`] +* link:{uri-stdlib-Mapping}#isNotEmpty[`Mapping.isNotEmpty`] +* link:{uri-stdlib-String}#isNotEmpty[`String.isNotEmpty`] +* link:{uri-stdlib-String}#isNotBlank[`String.isNotBlank`] == Breaking Changes [small]#💔# diff --git a/docs/modules/release-notes/pages/0.31.html b/docs/modules/release-notes/pages/0.31.html new file mode 100644 index 00000000..88c99818 --- /dev/null +++ b/docs/modules/release-notes/pages/0.31.html @@ -0,0 +1,826 @@ + + + + + + + +Pkl 0.31 Release Notes + + + + + + + + +
+
+
+ +
+

Pkl 0.31 was released on TBD.
+The latest bugfix release is 0.XX.0. (All Versions)

+
+
+

The next release (0.XX) is scheduled for ???.. +To see what’s coming in the future, follow the {uri-pkl-roadmap}[Pkl Roadmap].

+
+
+

Please send feedback and questions to GitHub Discussions, or submit an issue on GitHub.

+
+
+

Pkl is hosted on GitHub. +To get started, follow Installation.

+
+
+
+
+

Highlights 💖

+
+
+

News you don’t want to miss.

+
+
+

XXX

+ +
+
+
+
+

Noteworthy 🎶

+
+
+

Ready when you need them.

+
+
+

New standard library methods

+
+

The following APIs have been added to the standard library:

+
+ +
+
+
+
+

Breaking Changes 💔

+
+
+

Things to watch out for when upgrading.

+
+
+

XXX

+ +
+
+
+
+

Miscellaneous 🐸

+
+
+
    +
  • +

    XXX

    +
  • +
+
+
+
+
+

Bugs fixed 🐜

+
+
+

The following bugs have been fixed.

+
+
+
    +
  • +

    XXX (XXX)

    +
  • +
+
+
+
+
+

Contributors 🙏

+
+
+

We would like to thank the contributors to this release (in alphabetical order):

+
+
+
    +
  • +

    XXX

    +
  • +
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmMapping.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmMapping.java index f8f15931..fe160ddb 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmMapping.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmMapping.java @@ -181,4 +181,8 @@ public final class VmMapping extends VmListingOrMapping { cachedLength = count.get(); return cachedLength; } + + public boolean isEmpty() { + return getLength() == 0; + } } diff --git a/pkl-core/src/main/java/org/pkl/core/stdlib/base/ListNodes.java b/pkl-core/src/main/java/org/pkl/core/stdlib/base/ListNodes.java index 42352823..a36f952d 100644 --- a/pkl-core/src/main/java/org/pkl/core/stdlib/base/ListNodes.java +++ b/pkl-core/src/main/java/org/pkl/core/stdlib/base/ListNodes.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,6 +56,13 @@ public final class ListNodes { } } + public abstract static class isNotEmpty extends ExternalPropertyNode { + @Specialization + protected boolean eval(VmList self) { + return !self.isEmpty(); + } + } + public abstract static class lastIndex extends ExternalPropertyNode { @Specialization protected long eval(VmList self) { diff --git a/pkl-core/src/main/java/org/pkl/core/stdlib/base/ListingNodes.java b/pkl-core/src/main/java/org/pkl/core/stdlib/base/ListingNodes.java index 30488b94..cb40d397 100644 --- a/pkl-core/src/main/java/org/pkl/core/stdlib/base/ListingNodes.java +++ b/pkl-core/src/main/java/org/pkl/core/stdlib/base/ListingNodes.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,6 +46,13 @@ public final class ListingNodes { } } + public abstract static class isNotEmpty extends ExternalPropertyNode { + @Specialization + protected boolean eval(VmListing self) { + return !self.isEmpty(); + } + } + public abstract static class lastIndex extends ExternalPropertyNode { @Specialization protected long eval(VmListing self) { diff --git a/pkl-core/src/main/java/org/pkl/core/stdlib/base/MapNodes.java b/pkl-core/src/main/java/org/pkl/core/stdlib/base/MapNodes.java index e58728f3..a207658c 100644 --- a/pkl-core/src/main/java/org/pkl/core/stdlib/base/MapNodes.java +++ b/pkl-core/src/main/java/org/pkl/core/stdlib/base/MapNodes.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,6 +52,13 @@ public final class MapNodes { } } + public abstract static class isNotEmpty extends ExternalPropertyNode { + @Specialization + protected boolean eval(VmMap self) { + return !self.isEmpty(); + } + } + public abstract static class keys extends ExternalPropertyNode { @Specialization protected VmSet eval(VmMap self) { diff --git a/pkl-core/src/main/java/org/pkl/core/stdlib/base/MappingNodes.java b/pkl-core/src/main/java/org/pkl/core/stdlib/base/MappingNodes.java index cd0d2494..8b14049b 100644 --- a/pkl-core/src/main/java/org/pkl/core/stdlib/base/MappingNodes.java +++ b/pkl-core/src/main/java/org/pkl/core/stdlib/base/MappingNodes.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,6 @@ */ package org.pkl.core.stdlib.base; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.IndirectCallNode; import org.pkl.core.ast.lambda.ApplyVmFunction1Node; @@ -28,7 +27,6 @@ import org.pkl.core.stdlib.ExternalMethod0Node; import org.pkl.core.stdlib.ExternalMethod1Node; import org.pkl.core.stdlib.ExternalMethod2Node; import org.pkl.core.stdlib.ExternalPropertyNode; -import org.pkl.core.util.EconomicMaps; import org.pkl.core.util.MutableBoolean; import org.pkl.core.util.MutableReference; @@ -37,15 +35,15 @@ public final class MappingNodes { public abstract static class isEmpty extends ExternalPropertyNode { @Specialization - @TruffleBoundary protected boolean eval(VmMapping self) { - for (VmObjectLike curr = self; curr != null; curr = curr.getParent()) { - var cursor = EconomicMaps.getEntries(curr.getMembers()); - while (cursor.advance()) { - if (!(cursor.getKey() instanceof Identifier)) return false; - } - } - return true; + return self.isEmpty(); + } + } + + public abstract static class isNotEmpty extends ExternalPropertyNode { + @Specialization + protected boolean eval(VmMapping self) { + return !self.isEmpty(); } } diff --git a/pkl-core/src/main/java/org/pkl/core/stdlib/base/SetNodes.java b/pkl-core/src/main/java/org/pkl/core/stdlib/base/SetNodes.java index 285e4559..76f250d2 100644 --- a/pkl-core/src/main/java/org/pkl/core/stdlib/base/SetNodes.java +++ b/pkl-core/src/main/java/org/pkl/core/stdlib/base/SetNodes.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,6 +46,13 @@ public final class SetNodes { } } + public abstract static class isNotEmpty extends ExternalPropertyNode { + @Specialization + protected boolean eval(VmSet self) { + return !self.isEmpty(); + } + } + public abstract static class isEmpty extends ExternalPropertyNode { @Specialization protected boolean eval(VmSet self) { diff --git a/pkl-core/src/main/java/org/pkl/core/stdlib/base/StringNodes.java b/pkl-core/src/main/java/org/pkl/core/stdlib/base/StringNodes.java index d03c4abb..ead693f7 100644 --- a/pkl-core/src/main/java/org/pkl/core/stdlib/base/StringNodes.java +++ b/pkl-core/src/main/java/org/pkl/core/stdlib/base/StringNodes.java @@ -1,5 +1,5 @@ /* - * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. + * Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -131,6 +131,13 @@ public final class StringNodes { } } + public abstract static class isNotEmpty extends ExternalPropertyNode { + @Specialization + protected boolean eval(String self) { + return !self.isEmpty(); + } + } + public abstract static class isBlank extends ExternalPropertyNode { @Specialization protected boolean eval(String self) { @@ -138,6 +145,13 @@ public final class StringNodes { } } + public abstract static class isNotBlank extends ExternalPropertyNode { + @Specialization + protected boolean eval(String self) { + return !StringUtils.isBlank(self); + } + } + public abstract static class isRegex extends ExternalPropertyNode { @Specialization @TruffleBoundary diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/api/list.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/api/list.pkl index 5211e946..05db31ad 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/input/api/list.pkl +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/api/list.pkl @@ -12,6 +12,11 @@ facts { !list1.isEmpty } + ["isNotEmpty"] { + !List().isNotEmpty + list1.isNotEmpty + } + ["every()"] { list1.every((x) -> x <= 3) !list1.every((x) -> x > 2) diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/api/listing.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/api/listing.pkl index 44e9cd73..93ee0825 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/input/api/listing.pkl +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/api/listing.pkl @@ -42,7 +42,16 @@ facts { !altered.isEmpty !computedIndex.isEmpty } - + + ["isNotEmpty"] { + !empty.isNotEmpty + !empty2.isNotEmpty + base.isNotEmpty + derived.isNotEmpty + altered.isNotEmpty + computedIndex.isNotEmpty + } + ["lastIndex"] { empty.lastIndex == -1 empty2.lastIndex == -1 diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/api/map.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/api/map.pkl index 4a228aa0..4a178cb1 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/input/api/map.pkl +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/api/map.pkl @@ -8,6 +8,11 @@ facts { !map1.isEmpty } + ["isNotEmpty"] { + !Map().isNotEmpty + map1.isNotEmpty + } + ["containsKey()"] { map1.containsKey("two") !Map().containsKey("two") diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/api/mapping.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/api/mapping.pkl index 4842620e..7980c79e 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/input/api/mapping.pkl +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/api/mapping.pkl @@ -48,6 +48,13 @@ facts { empty2.isEmpty } + ["isNotEmpty"] { + base.isNotEmpty + derived.isNotEmpty + !empty.isNotEmpty + !empty2.isNotEmpty + } + ["containsKey()"] { base.containsKey("Pigeon") base.containsKey("Parrot") diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/api/set.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/api/set.pkl index 0e73308b..a47e6c5d 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/input/api/set.pkl +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/api/set.pkl @@ -12,6 +12,11 @@ facts { !set1.isEmpty } + ["isNotEmpty"] { + !Set().isNotEmpty + set1.isNotEmpty + } + ["every()"] { set1.every((x) -> x <= 3) !set1.every((x) -> x > 2) diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/api/string.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/api/string.pkl index 72417b13..c0ec950c 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/input/api/string.pkl +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/api/string.pkl @@ -11,6 +11,11 @@ facts { !str1.isEmpty } + ["isNotEmpty"] { + !"".isNotEmpty + str1.isNotEmpty + } + ["isBlank"] { "".isBlank " ".isBlank @@ -18,6 +23,13 @@ facts { !str1.isBlank } + ["isNotBlank"] { + !"".isNotBlank + !" ".isNotBlank + !"\t\n\r".isNotBlank + str1.isNotBlank + } + ["isBase64"] { "".isBase64 "AQIDBA==".isBase64 diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/api/list.pcf b/pkl-core/src/test/files/LanguageSnippetTests/output/api/list.pcf index 4442bba8..dc432e41 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/output/api/list.pcf +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/api/list.pcf @@ -3,6 +3,10 @@ facts { true true } + ["isNotEmpty"] { + true + true + } ["every()"] { true true diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/api/listing.pcf b/pkl-core/src/test/files/LanguageSnippetTests/output/api/listing.pcf index e3527d5a..3d7845ab 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/output/api/listing.pcf +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/api/listing.pcf @@ -7,6 +7,14 @@ facts { true true } + ["isNotEmpty"] { + true + true + true + true + true + true + } ["lastIndex"] { true true diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/api/map.pcf b/pkl-core/src/test/files/LanguageSnippetTests/output/api/map.pcf index db8770b9..78593786 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/output/api/map.pcf +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/api/map.pcf @@ -3,6 +3,10 @@ facts { true true } + ["isNotEmpty"] { + true + true + } ["containsKey()"] { true true diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/api/mapping.pcf b/pkl-core/src/test/files/LanguageSnippetTests/output/api/mapping.pcf index 5c6f7e4b..ad5a8378 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/output/api/mapping.pcf +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/api/mapping.pcf @@ -5,6 +5,12 @@ facts { true true } + ["isNotEmpty"] { + true + true + true + true + } ["containsKey()"] { true true diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/api/reflectedDeclaration.pcf b/pkl-core/src/test/files/LanguageSnippetTests/output/api/reflectedDeclaration.pcf index fde86b4d..39c32903 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/output/api/reflectedDeclaration.pcf +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/api/reflectedDeclaration.pcf @@ -830,6 +830,30 @@ alias { name = "isEmpty" allModifiers = Set() allAnnotations = List() + }, "isNotEmpty", new { + location { + line = XXXX + column = 3 + displayUri = "https://github.com/apple/pkl/blob/$commitId/stdlib/base.pkl#LXXXX" + } + docComment = """ + Tells whether this string is not empty. + + Facts: + ``` + !"".isNotEmpty + "abc".isNotEmpty + ``` + """ + annotations = List(new { + version = "0.31.0" + }) + modifiers = Set() + name = "isNotEmpty" + allModifiers = Set() + allAnnotations = List(new { + version = "0.31.0" + }) }, "isBlank", new { location { line = XXXX @@ -852,6 +876,32 @@ alias { name = "isBlank" allModifiers = Set() allAnnotations = List() + }, "isNotBlank", new { + location { + line = XXXX + column = 3 + displayUri = "https://github.com/apple/pkl/blob/$commitId/stdlib/base.pkl#LXXXX" + } + docComment = """ + Tells if at least one character is not Unicode "White_Space". + + Facts: + ``` + !"".isNotBlank + !" ".isNotBlank + "\\t\\n\\r".isNotBlank + "abc".isNotBlank + ``` + """ + annotations = List(new { + version = "0.31.0" + }) + modifiers = Set() + name = "isNotBlank" + allModifiers = Set() + allAnnotations = List(new { + version = "0.31.0" + }) }, "isRegex", new { location { line = XXXX @@ -1124,6 +1174,30 @@ alias { name = "isEmpty" allModifiers = Set() allAnnotations = List() + }, "isNotEmpty", new { + location { + line = XXXX + column = 3 + displayUri = "https://github.com/apple/pkl/blob/$commitId/stdlib/base.pkl#LXXXX" + } + docComment = """ + Tells whether this string is not empty. + + Facts: + ``` + !"".isNotEmpty + "abc".isNotEmpty + ``` + """ + annotations = List(new { + version = "0.31.0" + }) + modifiers = Set() + name = "isNotEmpty" + allModifiers = Set() + allAnnotations = List(new { + version = "0.31.0" + }) }, "isBlank", new { location { line = XXXX @@ -1146,6 +1220,32 @@ alias { name = "isBlank" allModifiers = Set() allAnnotations = List() + }, "isNotBlank", new { + location { + line = XXXX + column = 3 + displayUri = "https://github.com/apple/pkl/blob/$commitId/stdlib/base.pkl#LXXXX" + } + docComment = """ + Tells if at least one character is not Unicode "White_Space". + + Facts: + ``` + !"".isNotBlank + !" ".isNotBlank + "\\t\\n\\r".isNotBlank + "abc".isNotBlank + ``` + """ + annotations = List(new { + version = "0.31.0" + }) + modifiers = Set() + name = "isNotBlank" + allModifiers = Set() + allAnnotations = List(new { + version = "0.31.0" + }) }, "isRegex", new { location { line = XXXX diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/api/set.pcf b/pkl-core/src/test/files/LanguageSnippetTests/output/api/set.pcf index 833577cc..edf73b1a 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/output/api/set.pcf +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/api/set.pcf @@ -3,6 +3,10 @@ facts { true true } + ["isNotEmpty"] { + true + true + } ["every()"] { true true diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/api/string.pcf b/pkl-core/src/test/files/LanguageSnippetTests/output/api/string.pcf index 2baee5a3..f5b79bf0 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/output/api/string.pcf +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/api/string.pcf @@ -3,12 +3,22 @@ facts { true true } + ["isNotEmpty"] { + true + true + } ["isBlank"] { true true true true } + ["isNotBlank"] { + true + true + true + true + } ["isBase64"] { true true diff --git a/stdlib/base.pkl b/stdlib/base.pkl index 5e52f9f1..6c8aa5f4 100644 --- a/stdlib/base.pkl +++ b/stdlib/base.pkl @@ -1204,6 +1204,16 @@ external class String extends Any { /// ``` external isEmpty: Boolean + /// Tells whether this string is not empty. + /// + /// Facts: + /// ``` + /// !"".isNotEmpty + /// "abc".isNotEmpty + /// ``` + @Since { version = "0.31.0" } + external isNotEmpty: Boolean + /// Tells if all characters in this string have Unicode property "White_Space". /// /// Facts: @@ -1215,6 +1225,18 @@ external class String extends Any { /// ``` external isBlank: Boolean + /// Tells if at least one character is not Unicode "White_Space". + /// + /// Facts: + /// ``` + /// !"".isNotBlank + /// !" ".isNotBlank + /// "\t\n\r".isNotBlank + /// "abc".isNotBlank + /// ``` + @Since { version = "0.31.0" } + external isNotBlank: Boolean + /// Tells if this string is a valid regular expression according to [Regex]. external isRegex: Boolean @@ -1964,6 +1986,10 @@ class Listing extends Object { /// Tells if this listing is empty, that is, has zero elements. external isEmpty: Boolean + /// Tells if this listing is not empty, that is, it has at least one element. + @Since { version = "0.31.0" } + external isNotEmpty: Boolean + /// The index of the last element in this listing (same as `length - 1`). /// /// Returns `-1` for an empty list. @@ -2144,6 +2170,10 @@ class Mapping extends Object { /// Tells if this mapping is empty, that is, has zero entries. external isEmpty: Boolean + /// Tells whether this mapping is not empty, that is, it has at least one entry. + @Since { version = "0.31.0" } + external isNotEmpty: Boolean + /// The number of entries in this mapping. external length: Int @@ -2313,6 +2343,16 @@ abstract external class Collection extends Any { /// ``` abstract isEmpty: Boolean + /// Tells whether this collection is not empty. + /// + /// Facts: + /// ``` + /// List(1, 2, 3).isNotEmpty + /// !List().isNotEmpty + /// ``` + @Since { version = "0.31.0" } + abstract isNotEmpty: Boolean + /// The first element in this collection. /// /// Throws if this collection is empty. @@ -3015,6 +3055,9 @@ external class List extends Collection { external isEmpty: Boolean + @Since { version = "0.31.0" } + external isNotEmpty: Boolean + /// The index of the last element in this list (same as `length - 1`). /// /// Returns `-1` for an empty list. @@ -3303,8 +3346,12 @@ external const function Set(elements: VarArgs): Set /// ``` external class Set extends Collection { external length: Int + external isEmpty: Boolean + @Since { version = "0.31.0" } + external isNotEmpty: Boolean + external first: Element external firstOrNull: Element? @@ -3467,6 +3514,10 @@ external class Map extends Any { /// Tells whether this map is empty. external isEmpty: Boolean + /// Tells whether this map not empty. + @Since { version = "0.31.0" } + external isNotEmpty: Boolean + /// Returns the value for [key]. /// /// Returns [null] if this map does not contain [key].