Repository: apple/pkl
File: pkl-core/src/main/java/org/pkl/core/stdlib/base/ListingNodes.java (Java)

Code before:
  }

  public abstract static class getOrNull extends ExternalMethod1Node {
    @Specialization
    protected Object eval(VmListing self, long index) {
      if (index < 0 || index >= self.getLength()) {
        return VmNull.withoutDefault();
      }
      return VmUtils.readMember(self, index);
    }
  }

  public abstract static class getOrDefault extends ExternalMethod1Node {
    @Child private ApplyVmFunction1Node applyNode = ApplyVmFunction1Node.create();

    @Specialization
    protected Object eval(VmListing self, long index) {
      if (index < 0 || index >= self.getLength()) {
        if (VmUtils.readMember(self, Identifier.DEFAULT) instanceof VmFunction defaultFn) {
          return applyNode.execute(defaultFn, index);
        }
        throw PklBugException.unreachableCode();
      }
      return VmUtils.readMember(self, index);
    }
  }

  public abstract static class isDistinct extends ExternalPropertyNode {
    @Specialization
    @TruffleBoundary
    protected boolean eval(VmListing self) {
      var visitedValues = CollectionUtils.newHashSet();
      return self.forceAndIterateMemberValues((key, member, value) -> visitedValues.add(value));
    }
  }

  public abstract static class isDistinctBy extends ExternalMethod1Node {
    @Child private ApplyVmFunction1Node applyNode = ApplyVmFunction1Node.create();

    @Specialization
    protected boolean eval(VmListing self, VmFunction selector) {
      var visitedValues = CollectionUtils.newHashSet();
      return self.forceAndIterateMemberValues(
          (key, member, value) -> visitedValues.add(applyNode.execute(selector, value)));
    }
  }

  public abstract static class distinct extends ExternalPropertyNode {
    @Specialization
    protected VmListing eval(VmListing self) {
      var visitedValues = CollectionUtils.newHashSet();

Review comment (bug):
Two changes:

1. Create a cached IndirectCallNode, and pass it to `readMember` (share the same call node for each instance of `getOrDefault()`)
2. Just assert the return type as a `VmFunction` (no need for `PklBugException.unreachableCode()`)

```suggestion
  public abstract static class getOrDefault extends ExternalMethod1Node {
    @Child private IndirectCallNode callNode = IndirectCallNode.create();
    @Child private ApplyVmFunction1Node applyNode = ApplyVmFunction1Node.create();

    @Specialization
    protected Object eval(VmListing self, long index) {
      if (index < 0 || index >= self.getLength()) {
        var defaultFunction = (VmFunction) VmUtils.readMember(self, Identifier.DEFAULT, callNode);
        return applyNode.execute(defaultFunction, index);
      }
      return VmUtils.readMember(self, index, callNode);
    }
  }
```

Code after:
  }

  public abstract static class getOrNull extends ExternalMethod1Node {
    @Specialization
    protected Object eval(VmListing self, long index) {
      if (index < 0 || index >= self.getLength()) {
        return VmNull.withoutDefault();
      }
      return VmUtils.readMember(self, index);
    }
  }

  public abstract static class getOrDefault extends ExternalMethod1Node {
    @Child private IndirectCallNode callNode = IndirectCallNode.create();
    @Child private ApplyVmFunction1Node applyNode = ApplyVmFunction1Node.create();

    @Specialization
    protected Object eval(VmListing self, long index) {
      if (index < 0 || index >= self.getLength()) {
        var defaultFunction = (VmFunction) VmUtils.readMember(self, Identifier.DEFAULT, callNode);
        return applyNode.execute(defaultFunction, index);
      }
      return VmUtils.readMember(self, index);
    }
  }

  public abstract static class isDistinct extends ExternalPropertyNode {
    @Specialization
    @TruffleBoundary
    protected boolean eval(VmListing self) {
      var visitedValues = CollectionUtils.newHashSet();
      return self.forceAndIterateMemberValues((key, member, value) -> visitedValues.add(value));
    }
  }

  public abstract static class isDistinctBy extends ExternalMethod1Node {
    @Child private ApplyVmFunction1Node applyNode = ApplyVmFunction1Node.create();

    @Specialization
    protected boolean eval(VmListing self, VmFunction selector) {
      var visitedValues = CollectionUtils.newHashSet();
      return self.forceAndIterateMemberValues(
          (key, member, value) -> visitedValues.add(applyNode.execute(selector, value)));
    }
  }

  public abstract static class distinct extends ExternalPropertyNode {
    @Specialization
    protected VmListing eval(VmListing self) {
      var visitedValues = CollectionUtils.newHashSet();
      var builder = new VmObjectBuilder();