0: SomeClass1: "a"2: "b"3: "c"
0: instance of SomeClass1: "a"2: "b"3: "c"
OP_CONSTRUCTOP_CALL <symbol for initializer>
class Vector {this new(x, y) {_x = x_y = y}this polar(theta, radius) {_x = theta.cos * radius_y = theta.sin * radius}}
--
You received this message because you are subscribed to the Google Groups "Wren" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wren-lang+...@googlegroups.com.
To post to this group, send email to wren...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wren-lang/CAMu6JH93AwHsXJxqbdYA5Fz3M6sqL_x1XiF0acCvR2ZQnJVKMQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
While I really like Bjon idea of using 'new' as the constructor keyword (https://github.com/munificent/wren/pull/283#issuecomment-120517433), I think it will expose lots of problems regarding the auto construction of static metaclass 'new' and the possibility of the user to implement custom factories.
I mean if 'class Foo { new {} }' populates Foo and its metaclass with a method named 'new', the user can't properly redefine metaclass 'new' without creating an ambiguity in the compiler. So we need a way to distinguish 'automagic new' of 'new as a regular method'. This means that we need to to have 'new new () {}' as a constructor to allow 'new () {}' as a regular method. And all this defeat the interest of using 'new' as the keyword constructor.
In the end, while surprising at first, I think that Bob idea is better. By removing 'new' as a keyword, the 'new new' sentence is avoided (that sounds stupid to my ears) to make autoconstruct. While allowing the user to create factories transparently using something like:class Foo {static new (args...) {}new (args...) {}}since new is no longer a keyword.
So in the end to sum up, 'this' as a keyword in front of a method declaration only make it auto construct the static part which is a nice syntaxic sugar in the end.For the technicall part, if possible I would like an extra change to the compiler so that constructor functions are not specials as they are now. If you look at the compiler currently constructors are specials in the sence that they allways return 'this'. I really don't like that exception. It can be solve by changing a little the effect of the CONSTRUCT opcode so it transform the stack to:0: instance of SomeClass1: instance of SomeClass2: "a"3: "b"4: "c"And the assembly would look like:CONSTRUCT 3CALL 3, 'new(_,_,_)'RETURNIt involves moving the arguments and making an extra copy, but when performin CALL we then can discard its result and return the instance of SomeClass left on the stack.In addition since this requires CONSTRUCT to have the number of items to copy, so it must/can be made to work with the top of the stack instead of the bottom. This also make it more like and optimised/inlined version of what one would write for the *generic object factory* one would write like (in pseudo code):static new(args ...) {var instance = super.new() // or this.instantiate() (depending if meta class inheritance is available)instance.new(args...)return instance}
On Sat, Jul 11, 2015, at 10:01, Michel Hermier wrote:While I really like Bjon idea of using 'new' as the constructor keyword (https://github.com/munificent/wren/pull/283#issuecomment-120517433), I think it will expose lots of problems regarding the auto construction of static metaclass 'new' and the possibility of the user to implement custom factories.Hmm, I'm afraid I can't follow this. What is "auto construction of static metaclass 'new'"? Also, why would having the default "new" be a nameless static method pose a problem for custom factories?
I mean if 'class Foo { new {} }' populates Foo and its metaclass with a method named 'new', the user can't properly redefine metaclass 'new' without creating an ambiguity in the compiler. So we need a way to distinguish 'automagic new' of 'new as a regular method'. This means that we need to to have 'new new () {}' as a constructor to allow 'new () {}' as a regular method. And all this defeat the interest of using 'new' as the keyword constructor.In my proposal, "class Foo { new {} }" is simply invalid, because it tries to create a nameless constructor method without parameter list. Did you mean "class Foo { new() {} }"? That would declare an empty constructor method on the class, which can then be instantiated with "Foo()". However, this would already be the case by default. I do not understand why there would be a need to dinstinguish between the "automagic new" (you mean default constructor?) or "new as a regular method". Wouldn't it just be confusing to use "new" as a regular method? Possibly it's even invalid since you can't name a method the same as a keyword.In the end, while surprising at first, I think that Bob idea is better. By removing 'new' as a keyword, the 'new new' sentence is avoided (that sounds stupid to my ears) to make autoconstruct. While allowing the user to create factories transparently using something like:class Foo {static new (args...) {}new (args...) {}}since new is no longer a keyword.With making factories transparent, I guess you mean you can't dintinguish between when an actual constructor is called or when some regular static method is called that in turn instantiates something. You don't need "new" to be not a keyword for this:class FooInstance {}class Foo {static () { FooInstance() }}Here, class FooInstance relies on the default "new () {}" constructor, and Foo creates instances of FooInstance, but you call it the same way as if you are instantiating a "Foo":var foo = Foo()
So in the end to sum up, 'this' as a keyword in front of a method declaration only make it auto construct the static part which is a nice syntaxic sugar in the end.For the technicall part, if possible I would like an extra change to the compiler so that constructor functions are not specials as they are now. If you look at the compiler currently constructors are specials in the sence that they allways return 'this'. I really don't like that exception. It can be solve by changing a little the effect of the CONSTRUCT opcode so it transform the stack to:0: instance of SomeClass1: instance of SomeClass2: "a"3: "b"4: "c"And the assembly would look like:CONSTRUCT 3CALL 3, 'new(_,_,_)'RETURNIt involves moving the arguments and making an extra copy, but when performin CALL we then can discard its result and return the instance of SomeClass left on the stack.In addition since this requires CONSTRUCT to have the number of items to copy, so it must/can be made to work with the top of the stack instead of the bottom. This also make it more like and optimised/inlined version of what one would write for the *generic object factory* one would write like (in pseudo code):static new(args ...) {var instance = super.new() // or this.instantiate() (depending if meta class inheritance is available)instance.new(args...)return instance}While I do not fully understand where you're going with this pseudo code, I believe it could look like this when "new" was a keyword creating a static constructor method:static (args ...) {var instance = super() // or this.instantiate() (depending if meta class inheritance is available)instance(args...)return instance}The whole point is just that a nameless method is callable directly from the class (in case of static) or instance name. This should just make the code shorter to write and more pleasant to read. This should not be a factor in whether you can or can't write a generic object factory.
Hi,
It took me quite some time to read and formulate my thoughts on the patch.
While I really like Bjon idea of using 'new' as the constructor keyword (https://github.com/munificent/wren/pull/283#issuecomment-120517433), I think it will expose lots of problems regarding the auto construction of static metaclass 'new' and the possibility of the user to implement custom factories.
In the end, while surprising at first, I think that Bob idea is better. By removing 'new' as a keyword, the 'new new' sentence is avoided (that sounds stupid to my ears) to make autoconstruct. While allowing the user to create factories transparently using something like:
class Foo {
static new (args...) {
}
new (args...) {
}
}
class Foo {// Looks like a constructor, but returns a cached instance.static new(name) {if (__cache == null) __cache = {}if (__cache.containsKey(name)) {return __cache[name]}return __cache[name] = Foo.realNew(name)}this realNew(name) {_name = name}}
For the technicall part, if possible I would like an extra change to the compiler so that constructor functions are not specials as they are now. If you look at the compiler currently constructors are specials in the sence that they allways return 'this'. I really don't like that exception.
It can be solve by changing a little the effect of the CONSTRUCT opcode so it transform the stack to:
0: instance of SomeClass
1: instance of SomeClass
2: "a"
3: "b"
4: "c"
And the assembly would look like:
CONSTRUCT 3
CALL 3, 'new(_,_,_)'
RETURN
It involves moving the arguments and making an extra copy, but when performin CALL we then can discard its result and return the instance of SomeClass left on the stack.
In addition since this requires CONSTRUCT to have the number of items to copy, so it must/can be made to work with the top of the stack instead of the bottom.
This also make it more like and optimised/inlined version of what one would write for the *generic object factory* one would write like (in pseudo code):
static new(args ...) {
var instance = super.new() // or this.instantiate() (depending if meta class inheritance is available)
instance.new(args...)
return instance
}
About the changes you pushed to branch, I wonder if in the conversion process you didn't lost "new Object" forgeting to add new to Object metaclass (I didn't took the time to ensure this, I'm still experimenting the 'native code has frames' change, with mitiged results because of -Os inlining when it wants)
On Sat, Jul 11, 2015 at 1:01 AM, Michel Hermier <michel....@gmail.com> wrote:
Hi,
It took me quite some time to read and formulate my thoughts on the patch.
While I really like Bjon idea of using 'new' as the constructor keyword (https://github.com/munificent/wren/pull/283#issuecomment-120517433), I think it will expose lots of problems regarding the auto construction of static metaclass 'new' and the possibility of the user to implement custom factories.
That's right. If you want to have a static method named new that is not a constructor, that get's harder to specify. I think it's important to enable this because I want to fully encapsulate "factories" inside the class. A user shouldn't know whether a method they invoke on a class is a "real" constructor or some other kind of factory method.In the end, while surprising at first, I think that Bob idea is better. By removing 'new' as a keyword, the 'new new' sentence is avoided (that sounds stupid to my ears) to make autoconstruct. While allowing the user to create factories transparently using something like:
class Foo {
static new (args...) {
}
new (args...) {
}
}
Just to make it clearer, in this proposal, it would be something like:
class Foo {// Looks like a constructor, but returns a cached instance.static new(name) {if (__cache == null) __cache = {}
if (__cache.containsKey(name)) {return __cache[name]}
return __cache[name] = Foo.realNew(name)}
this realNew(name) {_name = name}}
This would let you do Foo.new(name), which looks like a normal constructor call, but which is actually just calling a static method. If we make new a reserved word, we'd have to come up with some special way to enable this.
For the technicall part, if possible I would like an extra change to the compiler so that constructor functions are not specials as they are now. If you look at the compiler currently constructors are specials in the sence that they allways return 'this'. I really don't like that exception.
Why don't you like this? It doesn't add much complexity to the compiler as far as I can tell.It can be solve by changing a little the effect of the CONSTRUCT opcode so it transform the stack to:
0: instance of SomeClass
1: instance of SomeClass
2: "a"
3: "b"
4: "c"
And the assembly would look like:
CONSTRUCT 3
CALL 3, 'new(_,_,_)'
RETURN
It involves moving the arguments and making an extra copy, but when performin CALL we then can discard its result and return the instance of SomeClass left on the stack.
In addition since this requires CONSTRUCT to have the number of items to copy, so it must/can be made to work with the top of the stack instead of the bottom.
This seems like more complexity than the current implementation. What's the reason to motivate this?
This also make it more like and optimised/inlined version of what one would write for the *generic object factory* one would write like (in pseudo code):
static new(args ...) {
var instance = super.new() // or this.instantiate() (depending if meta class inheritance is available)
instance.new(args...)
return instance
}
My hunch is that we don't want metaclass inheritance. From talking to a few old Smalltalkers, they generally consider it a mistake there. Also, Java, C++, C#, etc. have semantics more similar to not allowing metaclass inheritance (in other words, static methods aren't inherited), and it seems to work well there.
About the changes you pushed to branch, I wonder if in the conversion process you didn't lost "new Object" forgeting to add new to Object metaclass (I didn't took the time to ensure this, I'm still experimenting the 'native code has frames' change, with mitiged results because of -Os inlining when it wants)
You're correct, this is gone now. I think that's probably a feature more than a bug. I don't know if it's useful to be able to construct instances of Object so I just disabled that for now. If we do find a use for that, it's easy to give it a constructor.
On Sat, Jul 11, 2015 at 1:01 AM, Michel Hermier <michel....@gmail.com> wrote:Hi,
It took me quite some time to read and formulate my thoughts on the patch.
While I really like Bjon idea of using 'new' as the constructor keyword (https://github.com/munificent/wren/pull/283#issuecomment-120517433), I think it will expose lots of problems regarding the auto construction of static metaclass 'new' and the possibility of the user to implement custom factories.That's right. If you want to have a static method named new that is not a constructor, that get's harder to specify. I think it's important to enable this because I want to fully encapsulate "factories" inside the class. A user shouldn't know whether a method they invoke on a class is a "real" constructor or some other kind of factory method.In the end, while surprising at first, I think that Bob idea is better. By removing 'new' as a keyword, the 'new new' sentence is avoided (that sounds stupid to my ears) to make autoconstruct. While allowing the user to create factories transparently using something like:
class Foo {
static new (args...) {
}
new (args...) {
}
}Just to make it clearer, in this proposal, it would be something like:class Foo {// Looks like a constructor, but returns a cached instance.static new(name) {if (__cache == null) __cache = {}if (__cache.containsKey(name)) {return __cache[name]}return __cache[name] = Foo.realNew(name)}this realNew(name) {_name = name}}This would let you do Foo.new(name), which looks like a normal constructor call, but which is actually just calling a static method. If we make new a reserved word, we'd have to come up with some special way to enable this.
Simplify the compiler, and make the instance part of the constructor a regular function. Seeing the argument 'isConstructor' passed in the compiler is making me say we are doing something bad here.This seems like more complexity than the current implementation. What's the reason to motivate this?
Why would the constructor need to return 'this' it has to be a regular function. This would also the constructor to return a marker for its subclass:
class Foo {
this new { __id = __id != null ? __id + 1 : 0 }
}
class Bar is Foo {
this new {
if (super == 0) {IO.print("I'm the root of the universe") }
}
}
Well they might be a mistake, but it sounds logicall for some parts, else when writting stating methods and you need to call super static methods. Ohh wait in static 'this' is an in stance of Class, so we can use 'supertype', maybe it is enough to do the trick for most use case. I'm felling it was a great idea I introduced it ;)
My hunch is that we don't want metaclass inheritance. From talking to a few old Smalltalkers, they generally consider it a mistake there. Also, Java, C++, C#, etc. have semantics more similar to not allowing metaclass inheritance (in other words, static methods aren't inherited), and it seems to work well there.
Instantiation is the common place where class needs to be remebered, and is generaly why metaclass inheritance is introduced I guess (so that super.new return an instance of the correct class). Not having them adds a little annoyance in that one as to rewrite 'static new' calls to use custom allocations strategies of parent class.
Ex1: Rethink of your example with a subclass of Foo that want to be in the cache.
class Foo {// Looks like a constructor, but returns a cached instance.
static new(name) { createIfUncached(name, Foo) }
this realNew(name) {_name = name}
static createIfUncached(name, clas) {
if (__cache == null) __cache = {}if (__cache.containsKey(name)) {return __cache[name]}
return __cache[name] = clas.realNew(name)}}class Bar is Foo {static new(name) { createIfUncached(name, Bar) }this realNew(name) {super(name)}}
Ex2: In a *real* usage, an abstract resource loader providing factory throught Ressource.new(path) and a dedicated ones ImageRessource.new(path), SoundRessource.new(path)... (I can explain more on this if you don't see what I mean).
I hope these are pretty rare to justify the needed extra code.
But I agree enabling metaclass inheritance might be worse because __vars become class vars and not real static ones, making more problems than it solves.
You're correct, this is gone now. I think that's probably a feature more than a bug. I don't know if it's useful to be able to construct instances of Object so I just disabled that for now. If we do find a use for that, it's easy to give it a constructor.
There is one pretty used, the unique object that act as a marker for something and that is not possibly null (like tombstone in our map implementation).
Similar to PHP. Very clear. But also painfully long for something almost every class will use.
Clear. Shorter. I think it reads well with the following method name:class Foo {construct new() { ... } // "construct new ..."construct fromBar() { ... } // "construct from bar ..."}
Very short, which is nice, but cryptic to anyone not familiar with it.
We want to make this usable as a method name, so we'd have to do something like a contextual keyword. Those are a bit fishy. Also leads to weird code like:class Foo {new new() { ... }}
Short and fairly intuitive. But reserves "init" which is a pretty commonly used identifier.
Kind of long. Familiar to Ruby programmers.
--You received this message because you are subscribed to the Google Groups "Wren" group.To unsubscribe from this group and stop receiving emails from it, send an email to wren-lang+...@googlegroups.com.To post to this group, send email to wren...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wren-lang/CAMu6JH8KR-BoEN0AN_W%2BdZio-u2xg3_e%2Bn7BZzy%2B352rYeajCQ%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wren-lang/1437403190.3081852.328241577.1EEF332A%40webmail.messagingengine.com.
construct looks good. But we didn't explored the non keyword way, what do you think about using an operartor, something like:
*new() {}
+new() {}
@new() {}
or something else.
What do you think of this ?
To view this discussion on the web visit https://groups.google.com/d/msgid/wren-lang/CAOHyZobMbzxx%2ByPgJ9J53RL38jHc8Omg8LRVVi4mdmkFh9V3Xw%40mail.gmail.com.
Replying to myself or even:
@construct new
So it does look like a decorator...
construct looks good. But we didn't explored the non keyword way, what do you think about using an operartor, something like:
*new() {}
+new() {}
@new() {}
or something else.What do you think of this ?
class Person {construct new(name) {_name = name}}
class Person {*new(name) {_name = name}}
--
You received this message because you are subscribed to the Google Groups "Wren" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wren-lang+...@googlegroups.com.
To post to this group, send email to wren...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wren-lang/CAMu6JH8pVHHC2fGtZ%3DLmCx93QdvPDUR8fmYKiZzEhd%3DoAHi%3Dtw%40mail.gmail.com.
You didn't commented about the decorator syntax I proposed after that, like:
class Foo {
@construct new () { }
}
It really looks like an interesting way to do it while not *really* using a keyword while still beeing readable.
And that way if we introduce the decorators, it only makes it a special decorator (if we can't make it a real decorator).
--
You received this message because you are subscribed to the Google Groups "Wren" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wren-lang+...@googlegroups.com.
To post to this group, send email to wren...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wren-lang/CAMu6JH_qnxzbKQ-Teeiv4p4CpsUKPKyNqZD58Rfy2iw88cPGRA%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "Wren" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wren-lang+...@googlegroups.com.
To post to this group, send email to wren...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wren-lang/CAMu6JH8VuRbyx0sg4WWTT6-0JyAWz5XbCNnmF3hTRswJ85UyZA%40mail.gmail.com.
Even if we adopt the '@' (or what ever) we can allways make it a cheap exception in the compiler, so that 'construct' is interpreted as '@construct', so adopting it right now is *not* important.
I think the more important question is "do we want decorators? how implement them if feasable?"