No way to reference function property or let binding from object that defines a property with the same name #363

Open
opened 2025-12-30 01:23:50 +01:00 by adam · 3 comments
Owner

Originally created by @sin-ack on GitHub (Nov 7, 2025).

Reproduced in Pkl 0.30.0.

In my code it's a common pattern to compute an intermediate property with a let binding, like this:

function frobnicate(arg: String) =
    let (foo = process(arg))
        new Frobnication {
            foo = foo
        }

However this naive version causes a stack overflow. Unfortunately, none of the other scoping keywords help me here:

  • this references the Frobnication object being created.
  • outer references the class/module on which .frobnicate() was called.
  • super references the superclass of Frobnication if any.
  • module references the containing module.

In particular, for function properties this means I have to either uglify my parameters or define aliases:

// Shows up in Pkldoc, not great :(
function frobnicate(foo_: String) = new Frobnication {
    foo = foo_
}

// Extra let binding
function frobnicate(foo: String) =
    let (foo_ = foo)
        new Frobnication {
            foo = foo_
        }

I'm not quite sure what a nice way to solve this is. outer feels like the closest candidate that should work for this purpose, but it might mean that logically, an "intermediate" object is created which represents the method's scope (closure?).

Originally created by @sin-ack on GitHub (Nov 7, 2025). Reproduced in Pkl 0.30.0. In my code it's a common pattern to compute an intermediate property with a `let` binding, like this: ```pkl function frobnicate(arg: String) = let (foo = process(arg)) new Frobnication { foo = foo } ``` However this naive version causes a stack overflow. Unfortunately, none of the other scoping keywords help me here: - `this` references the `Frobnication` object being created. - `outer` references the class/module on which `.frobnicate()` was called. - `super` references the superclass of `Frobnication` if any. - `module` references the containing module. In particular, for function properties this means I have to either uglify my parameters or define aliases: ```pkl // Shows up in Pkldoc, not great :( function frobnicate(foo_: String) = new Frobnication { foo = foo_ } // Extra let binding function frobnicate(foo: String) = let (foo_ = foo) new Frobnication { foo = foo_ } ``` I'm not quite sure what a nice way to solve this is. `outer` feels like the closest candidate that should work for this purpose, but it might mean that logically, an "intermediate" object is created which represents the method's scope (closure?).
Author
Owner

@bioball commented on GitHub (Nov 7, 2025):

Using an underscore is the normal way to do this. Currently, there's no way to disambiguate referencing the function parameter.

By the way, as an aside: it's also not recommended to have "builder" methods that simply return new object instances. Typically, you would just create those objects directly instead.

@bioball commented on GitHub (Nov 7, 2025): Using an underscore is the normal way to do this. Currently, there's no way to disambiguate referencing the function parameter. By the way, as an aside: it's also not recommended to have "builder" methods that simply return new object instances. Typically, you would just create those objects directly instead.
Author
Owner

@sin-ack commented on GitHub (Nov 7, 2025):

The function does much more than shown here, which is why it's done in this way. It computes a bunch of stuff from the given arguments.

@sin-ack commented on GitHub (Nov 7, 2025): The function does much more than shown here, which is why it's done in this way. It computes a bunch of stuff from the given arguments.
Author
Owner

@bioball commented on GitHub (Nov 7, 2025):

The function does much more than shown here, which is why it's done in this way. It computes a bunch of stuff from the given arguments.

Makes sense!

@bioball commented on GitHub (Nov 7, 2025): > The function does much more than shown here, which is why it's done in this way. It computes a bunch of stuff from the given arguments. Makes sense!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/pkl#363