I'm sitting here programming for a small project I have, and I am reminded of something that bugs the heck out of me...
class Foo:
def __init__(self, foo, bar, baz):
self.foo = foo
self.bar = bar
self.baz = baz
Excuse the python, but it happens in a lot of OO languages. I think it would be swift as hell if there was a shorthand for this boilerplate. Something like
class Foo
{
new make(foo, bar, baz)
{
assign foo, bar, baz
}
}
And this would automatically assign member variables to the values held by the parameters in scope of the same name.
andySun 4 May 2008
In alot of our latest code, we've been moving away from constructors that take parameters (unless of course it makes the most sense). So typically I'd write that code as:
class Foo
{
Int foo
Int bar
Int baz
}
foo := Foo { foo=5; bar=8; baz=9; }
I've found that works rather well for most cases.
heliumSun 4 May 2008
I thought about something along this lines.
class Foo (Int bar, Int baz, Int qux) {
}
This would than create members as well as a constructor that initializes them. But using what andy just suggested might be a better option as you don't have to add any syntax.
tacticsSun 4 May 2008
Sometimes, you do have to have additional variables initialized. And sometimes having to remember only the position is nicer than having to remember the spellings of the members.
@helium I don't know if I like the implicit assignment. The assign syntax I proposed at least tips off new users that something is afoot in the constructor. Otherwise, it just looks like an empty and erroneous constructor.
heliumMon 5 May 2008
Hmmm, perhaps it's just because I'm used to it from another language. To me it's pretty obvious that something outside the class body can't be a normal constructor. So if I don't know what it means I'd look it up. For somebody only knowing Java the Ruby-like closure syntax will look strange as well.
class Point (Int x, Int y) {
Void moveBy (Int byX, Int byY)
{
x += byX
y += byY
}
Void moveTo (Int toX, Int toY)
{
x = toX
y = toY
}
}
vs
class Point {
Int x
Int y
Point (Int x, Int y)
{
this.x = x
this.Y = y
}
Void moveBy (Int byX, Int byY)
{
x += byX
y += byY
}
Void moveTo (Int toX, Int toY)
{
x = toX
y = toY
}
}
The only disadvantage of andy's solution is that it doesn't work with immutable objects, while tactics' and mine do.
Oh, and assign might be name you'd like to use for method names?
tacticsMon 5 May 2008
Maybe assign isn't the best keyword to use.
Maybe assigning. Gerunds make for good keywords. Or maybe it's that they make bad method and slot names.
class Point (Int x, Int y) {
...
}
Ah, I misread your first post, helium. This syntax is interesting. However, it's weird how the slots are defined in a strange place. I'm also not sure how it would interact with other slots that need to be assigned in a constructor.
I would like that idea a lot, though, if like enum, it was given a different keyword with different semantics. To recycle historical keywords, it could be something like struct:
struct Point(Int x, Int y) {
...
}
These would just be very stripped down, lightweight classes, where you want to save boilerplate and lines of code. It would automatically create the slots given after the struct name, and no other slots could be defined. Then, it would provide an implicit, auto-assigning constructor based on the signature given: new make(Int x, Int y) in this case. I suppose there wouldn't be a clear way to do subclassing of structs. But they would act simple, lightweight, type-checked records in the language.
andyMon 5 May 2008
@helium - the serialization syntax actually does work with immutable objects.
brianMon 5 May 2008
This has been a great discussion - I agree that ctor assignment can result in a lot of boiler plate.
Although as Andy mentions, we've started thinking that constructors which take a bunch of parameters shouldn't actually be used by convention - but rather that we should use the with-block syntax (which does work with const fields too):
foo := Foo { foo=5; bar=8; baz=9; }
So if we decide that should be convention, then I'm not sure we should create special syntax for constructors?
One other thing which is a lot of boiler plate related to constructors and super calls is passing thru parameters:
new make(Str foo, Str bar, Str baz)
: super(foo, bar, baz)
{
}
It would be nice in situations like this to skip the parameters if they are exactly the same:
new make(Str foo, Str bar, Str baz)
: super
{
}
mikeTue 6 May 2008
The with-block syntax is nice, but having it as the only solution would get on my nerves after a while. I don't want to have to type the variables names every time.
I really like tactics' original idea. I'm neutral on the assign keyword syntax, but the concept of avoiding the this.foo == foo boilerplate is a great idea.
tactics Sun 4 May 2008
I'm sitting here programming for a small project I have, and I am reminded of something that bugs the heck out of me...
Excuse the python, but it happens in a lot of OO languages. I think it would be swift as hell if there was a shorthand for this boilerplate. Something like
And this would automatically assign member variables to the values held by the parameters in scope of the same name.
andy Sun 4 May 2008
In alot of our latest code, we've been moving away from constructors that take parameters (unless of course it makes the most sense). So typically I'd write that code as:
I've found that works rather well for most cases.
helium Sun 4 May 2008
I thought about something along this lines.
This would than create members as well as a constructor that initializes them. But using what andy just suggested might be a better option as you don't have to add any syntax.
tactics Sun 4 May 2008
Sometimes, you do have to have additional variables initialized. And sometimes having to remember only the position is nicer than having to remember the spellings of the members.
@helium I don't know if I like the implicit assignment. The
assign
syntax I proposed at least tips off new users that something is afoot in the constructor. Otherwise, it just looks like an empty and erroneous constructor.helium Mon 5 May 2008
Hmmm, perhaps it's just because I'm used to it from another language. To me it's pretty obvious that something outside the class body can't be a normal constructor. So if I don't know what it means I'd look it up. For somebody only knowing Java the Ruby-like closure syntax will look strange as well.
vs
The only disadvantage of andy's solution is that it doesn't work with immutable objects, while tactics' and mine do.
Oh, and
assign
might be name you'd like to use for method names?tactics Mon 5 May 2008
Maybe assign isn't the best keyword to use.
Maybe
assigning
. Gerunds make for good keywords. Or maybe it's that they make bad method and slot names.Ah, I misread your first post, helium. This syntax is interesting. However, it's weird how the slots are defined in a strange place. I'm also not sure how it would interact with other slots that need to be assigned in a constructor.
I would like that idea a lot, though, if like
enum
, it was given a different keyword with different semantics. To recycle historical keywords, it could be something likestruct
:These would just be very stripped down, lightweight classes, where you want to save boilerplate and lines of code. It would automatically create the slots given after the struct name, and no other slots could be defined. Then, it would provide an implicit, auto-assigning constructor based on the signature given: new make(Int x, Int y) in this case. I suppose there wouldn't be a clear way to do subclassing of structs. But they would act simple, lightweight, type-checked records in the language.
andy Mon 5 May 2008
@helium - the serialization syntax actually does work with immutable objects.
brian Mon 5 May 2008
This has been a great discussion - I agree that ctor assignment can result in a lot of boiler plate.
Although as Andy mentions, we've started thinking that constructors which take a bunch of parameters shouldn't actually be used by convention - but rather that we should use the with-block syntax (which does work with const fields too):
So if we decide that should be convention, then I'm not sure we should create special syntax for constructors?
One other thing which is a lot of boiler plate related to constructors and super calls is passing thru parameters:
It would be nice in situations like this to skip the parameters if they are exactly the same:
mike Tue 6 May 2008
The with-block syntax is nice, but having it as the only solution would get on my nerves after a while. I don't want to have to type the variables names every time.
I really like tactics' original idea. I'm neutral on the
assign
keyword syntax, but the concept of avoiding thethis.foo == foo
boilerplate is a great idea.