Am I missing something or is it the expected behavior ?
Originally created by @hmonfleur on GitHub (Jul 10, 2024).
I want to refer to functions through their identifiers.
Declaring a function and a class:
```pkl
function foo():Int = 1
class A{
hidden f: () -> Int
x = f.apply()
}
```
Instantiating the following object:
```pkl
a = new A{
f = foo
}
```
[produces](https://pkl-playground.vercel.app/?share=unless-enough-deeply):
```Cannot find property `foo`.```
Being unsure of how to refer to "foo" I also tried:
```pkl
a = new A{
f = module.foo
}
```
Which [produces](https://pkl-playground.vercel.app/?share=forget-saddle-laugh):
```Cannot find property `foo` in module `text`.```
However the following code:
```pkl
hidden foo = () -> 1
class A{
hidden f: () -> Int
x = f.apply()
}
a = new A{
f = foo // same behavior with module.foo
}
```
[produces](https://pkl-playground.vercel.app/?share=truck-species-screen):
```pkl
{
"a": {
"x": 1
}
}
```
Am I missing something or is it the expected behavior ?
Unfortunately, this is more complicated than you'd hope. Functions and properties have entirely different namespaces in Pkl. This means that you can have a function foo() and a property foo side-by-side without issue, but it also means that, notationally, functions are not as first-class as you'd like (believe me, I've wanted this too). If you want to pass a function as a function-typed-value, you have to wrap it in a lambda;
function foo():Int = 1
class A {
hidden f: () -> Int
x = f.apply()
}
a: A = new { // <- side-note; prefer type signatures, because `new A {` doesn't imply at all that `a: A`.
f = () -> foo() // <- this works
}
Here's a thing to consider (and I'm mindful you probably reduced the real example to get here); whenever you write a zero-argument function in Pkl, alarm bells should be ringing. You never need those; since there are no side-effects, there's no reason to postpone evaluation "manually," and since Pkl is late-bound, all properties essentially are zero-arity functions.
@holzensp commented on GitHub (Jul 12, 2024):
Unfortunately, this is more complicated than you'd hope. Functions and properties have _entirely different namespaces_ in Pkl. This means that you can have a function `foo()` and a property `foo` side-by-side without issue, but it also means that, notationally, functions are not as first-class as you'd like (believe me, I've wanted this too). If you want to pass a `function` as a function-typed-value, you have to wrap it in a lambda;
```pkl
function foo():Int = 1
class A {
hidden f: () -> Int
x = f.apply()
}
a: A = new { // <- side-note; prefer type signatures, because `new A {` doesn't imply at all that `a: A`.
f = () -> foo() // <- this works
}
```
Here's a thing to consider (and I'm mindful you probably reduced the real example to get here); whenever you write a zero-argument function in Pkl, alarm bells should be ringing. You never need those; since there are no side-effects, there's no reason to postpone evaluation "manually," and since Pkl is late-bound, all properties _essentially are zero-arity functions_.
Closing this; if you need to refer to a function as a value, use a lambda notation like @holzensp mentioned. Methods (those that start with a function keyword) can't be passed as a value.
@bioball commented on GitHub (Jul 22, 2024):
Closing this; if you need to refer to a function as a value, use a lambda notation like @holzensp mentioned. Methods (those that start with a `function` keyword) can't be passed as a value.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Originally created by @hmonfleur on GitHub (Jul 10, 2024).
I want to refer to functions through their identifiers.
Declaring a function and a class:
Instantiating the following object:
produces:
Cannot find property `foo`.Being unsure of how to refer to "foo" I also tried:
Which produces:
Cannot find property `foo` in module `text`.However the following code:
produces:
Am I missing something or is it the expected behavior ?
@holzensp commented on GitHub (Jul 12, 2024):
Unfortunately, this is more complicated than you'd hope. Functions and properties have entirely different namespaces in Pkl. This means that you can have a function
foo()and a propertyfooside-by-side without issue, but it also means that, notationally, functions are not as first-class as you'd like (believe me, I've wanted this too). If you want to pass afunctionas a function-typed-value, you have to wrap it in a lambda;Here's a thing to consider (and I'm mindful you probably reduced the real example to get here); whenever you write a zero-argument function in Pkl, alarm bells should be ringing. You never need those; since there are no side-effects, there's no reason to postpone evaluation "manually," and since Pkl is late-bound, all properties essentially are zero-arity functions.
@bioball commented on GitHub (Jul 22, 2024):
Closing this; if you need to refer to a function as a value, use a lambda notation like @holzensp mentioned. Methods (those that start with a
functionkeyword) can't be passed as a value.