Originally created by @jw-y on GitHub (Mar 14, 2024).
tmp.pkl
```
class Bar {
foos: Listing<String>
}
foos = new {
"hi"
}
bar = new {
foos = foos
}
```
```bash
pkl eval tmp.pkl
```
Eval doesn't finish while
tmp2.pkl
```
class Bar {
foos: Listing<String>
}
foo = new {
"hi"
}
bar = new {
foos = foo
}
```
```bash
pkl eval tmp2.pkl
```
Here eval outputs correctly.
I get that `foos` in rhs of `foos=foos` is referring to it it's own, `Bar`'s `foos`,
therefore the infinite loop, but I think this is counter-intuitive
or is it duplicate of #117
I guess it is "intuitive" 🤔
You create a new object by extending Bar.
In your new object you set the variable to the exact same variable. => Recursive.
If you want to use the one from your parent class, you can use super.foos.
And this works 🙃
See https://pkl-playground.vercel.app/?share=officer-bush-group
@StefMa commented on GitHub (Mar 14, 2024):
I guess it is "intuitive" 🤔
You create a new object by extending `Bar`.
In your new object you set the variable to the exact same variable. => Recursive.
If you want to use the one from your parent class, you can use `super.foos`.
And this works 🙃
See https://pkl-playground.vercel.app/?share=officer-bush-group
This is expected behavior (you can't define a property in terms of itself).
In order to reference the outer foo, you'll need to qualify that reference somehow so that Pkl knows that you're referring to a different foo.
In your case, you can either use module.foo, or outer.foo, because foo is defined on the module and it is one lexical scope higher.
In the case where it's not available off module, it's common to do something like this:
bar{localself=thisfoo=1baz{biz{foo=self.foo}}}
@bioball commented on GitHub (Mar 14, 2024):
This is expected behavior (you can't define a property in terms of itself).
In order to reference the outer `foo`, you'll need to qualify that reference somehow so that Pkl knows that you're referring to a _different_ foo.
In your case, you can either use `module.foo`, or `outer.foo`, because `foo` is defined on the module _and_ it is one lexical scope higher.
In the case where it's not available off `module`, it's common to do something like this:
```groovy
bar {
local self = this
foo = 1
baz {
biz {
foo = self.foo
}
}
}
```
Thanks for the replies!
I was actually going for builder pattern in the following way
function BarBuilder(foo) = new Bar { foo = foo }
In most programming languages (if not all), you would expect foo on the rhs to refer to function Bird's argument.
This is "counter-intuitive" in terms of other programming languages.
I guess this boils down to pkl's two traits
pkl doesn't need special keyword like this or self to refer to it's own member
pkl gives precedence to its own members over outside local variables
I guess this is a quirk of pkl?
@jw-y commented on GitHub (Mar 15, 2024):
Thanks for the replies!
I was actually going for builder pattern in the following way
```
function BarBuilder(foo) = new Bar { foo = foo }
```
In most programming languages (if not all), you would expect `foo` on the rhs to refer to `function Bird`'s argument.
This is "counter-intuitive" in terms of other programming languages.
I guess this boils down to pkl's two traits
1. pkl doesn't need special keyword like `this` or `self` to refer to it's own member
2. pkl gives precedence to its own members over outside local variables
I guess this is a quirk of pkl?
It's actually not due to implicit this; it's because foo is in the lexical scope.
Other languages that have similar scoping rules have similar quirks. For example, the following java is also defining variable name in terms of itself, instead of assigning to the outer name:
Both p1 and p2 are the same thing, but p1 is more readable, and it's also clearer what 31 is in the first example because it's named.
@bioball commented on GitHub (Mar 15, 2024):
It's actually not due to implicit `this`; it's because `foo` is in the lexical scope.
Other languages that have similar scoping rules have similar quirks. For example, the following java is also defining variable `name` in terms of itself, instead of assigning to the outer `name`:
```java
class Person {
private final String name;
public Person(String name) {
name = name;
}
}
```
To fix, you need to qualify _which_ `name` you're talking about:
```diff
public Person(String name) {
- name = name;
+ this.name = name;
}
```
Also, BTW: the builder pattern generally isn't that useful in Pkl, because Pkl objects already fulfill the role of a "builder".
Consider:
```groovy
class Person {
name: String
age: Int
}
function Person(_name: String, _age: Int): Person = new { name = _name; age = _age }
p1: Person = new {
name = "Susan"
age = 31
}
p2: Person = Person("Susan", 31)
```
Both `p1` and `p2` are the same thing, but `p1` is more readable, and it's also clearer what `31` is in the first example because it's named.
Closing this as an issue, but feel free to keep commenting if you want to learn more about scoping or coding style!
@bioball commented on GitHub (Mar 15, 2024):
Closing this as an issue, but feel free to keep commenting if you want to learn more about scoping or coding style!
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 @jw-y on GitHub (Mar 14, 2024).
tmp.pkl
Eval doesn't finish while
tmp2.pkl
Here eval outputs correctly.
I get that
foosin rhs offoos=foosis referring to it it's own,Bar'sfoos,therefore the infinite loop, but I think this is counter-intuitive
or is it duplicate of #117
@StefMa commented on GitHub (Mar 14, 2024):
I guess it is "intuitive" 🤔
You create a new object by extending
Bar.In your new object you set the variable to the exact same variable. => Recursive.
If you want to use the one from your parent class, you can use
super.foos.And this works 🙃
See https://pkl-playground.vercel.app/?share=officer-bush-group
@bioball commented on GitHub (Mar 14, 2024):
This is expected behavior (you can't define a property in terms of itself).
In order to reference the outer
foo, you'll need to qualify that reference somehow so that Pkl knows that you're referring to a different foo.In your case, you can either use
module.foo, orouter.foo, becausefoois defined on the module and it is one lexical scope higher.In the case where it's not available off
module, it's common to do something like this:@jw-y commented on GitHub (Mar 15, 2024):
Thanks for the replies!
I was actually going for builder pattern in the following way
In most programming languages (if not all), you would expect
fooon the rhs to refer tofunction Bird's argument.This is "counter-intuitive" in terms of other programming languages.
I guess this boils down to pkl's two traits
thisorselfto refer to it's own memberI guess this is a quirk of pkl?
@bioball commented on GitHub (Mar 15, 2024):
It's actually not due to implicit
this; it's becausefoois in the lexical scope.Other languages that have similar scoping rules have similar quirks. For example, the following java is also defining variable
namein terms of itself, instead of assigning to the outername:To fix, you need to qualify which
nameyou're talking about:Also, BTW: the builder pattern generally isn't that useful in Pkl, because Pkl objects already fulfill the role of a "builder".
Consider:
Both
p1andp2are the same thing, butp1is more readable, and it's also clearer what31is in the first example because it's named.@bioball commented on GitHub (Mar 15, 2024):
Closing this as an issue, but feel free to keep commenting if you want to learn more about scoping or coding style!
@jw-y commented on GitHub (Mar 17, 2024):
Got it! Thanks for the detailed reply!