Parameters to constructor

BlitzMax Forums/BlitzMax Beginners Area/Parameters to constructor

SillyPutty(Posted 2005) [#1]
Hi all

I am having trouble passing parameters to my constructors.

Example:

type player
field player_size:float
method new(size:int)
player_size = size
end method
end type

Player1:player = new player(20)


skn3(Posted 2005) [#2]
You cant pass params to the constructor.


SillyPutty(Posted 2005) [#3]
ok thanks dude.

Will do a workaround.


Bot Builder(Posted 2005) [#4]
You can however, make a create function (any name works):

Type player
 Field player_size:float
 Function Create(size:int)
  n:player=new player
  n.player_size=size
  Return n
 End Function
End Type



SillyPutty(Posted 2005) [#5]
yeah, that is what i am doing, thanks :)


octothorpe(Posted 2005) [#6]
Feels like a kludge :(

I think constructors should take arguments


FlameDuck(Posted 2005) [#7]
Feels like a kludge :(
It isn't. It's called a "Simple Factory" pattern, and it solves a lot of creation issue, even in languages that have constructors that take parameters.

BlitzMAX uses them extensively. CreateList, CreateImage, CreatePixmap, CreateWindows, CreateGraphics, etc...


octothorpe(Posted 2005) [#8]
It's called a "Simple Factory" pattern


It isn't. A Simple Factory Pattern returns an instance of one of several classes depending upon the parameters passed to the factory method, which is something that constructors alone cannot do.

Parameters taken by constructors are typically used to initialize member variables.


PGF(Posted 2005) [#9]
The kludge feeling would be reduced if you BlitzMax implemented:

a) Method overloading
b) Derived functions that can return compatible derived types

Type T_Place

	Field Name:String

	Function Create:T_Place (name:String)
		Local obj:T_Place = New T_Place
		
		obj.Name = name
		
		Return obj
	End Function

End Type

Type T_City Extends T_Place

	Field Population:Int
	
	Function Create:T_City (name:String, population:Int)
		Local obj:T_City = New T_City
		
		obj.Name = name
		obj.population = population
		
		Return obj
	End Function
	
End Type

This gives a compile error: "Overriding method differs by type".

So the derived type factory has to be called something else like CreateCity and you say:

Local city:T_City = T_City.CreateCity("Sydney", 3276207)

Whereas I'd like to say:

Local city:T_City = new T_City("Sydney", 3276207)

Also the derived type has no built-in way to pass parameters to its base type constructor so you end up having to implement yet another differently named method in each type for its descendents to set its parameters

' Star type - These guys shine and occasionally explode
Type T_Star Extends T_Natural

	Function CreateStar:T_Star(name:String, pos:T_Pos, vel:T_Pos, colour:T_Colour, mass:Float, radius:Float, rot:Float, rotRate:Float)
		Local obj:T_Star = New T_Star

		obj.SetStarParms(name, pos, vel, colour, mass, radius, rot, rotRate)
		
		Return obj
	End Function

	Method SetStarParms(name:String, pos:T_Pos, vel:T_Pos, colour:T_Colour, mass:Float, radius:Float, rot:Float, rotRate:Float)
	
		super.SetNaturalParms(name, pos, vel, colour, mass, radius, rot, rotRate)
	
	End Method
	
End Type

Here T_Star is derived from T_Natural and happens to have the same parameters although it could have additional ones or even not have some but provide defaults. I regard it as duplication for T_Star to directly set the properties that it inherits from T_Natural. It should be possible to pass these to the super constructor in a minimal way.

I'd like to see something like the following in BlitzMax (based on C# syntax):
' Star type - These guys shine and occasionally explode
Type T_Star Extends T_Natural

	Method New(name:String, pos:T_Pos, vel:T_Pos, colour:T_Colour, mass:Float, radius:Float, rot:Float, rotRate:Float)
	: base(name, pos, vel, colour, mass, radius, rot, rotRate)
	'  Anything else you want to initialise here
	End Method

End Type

Add in that you might want constructors with various parameters and you start to write things like:

' Default empty constructor
Function CreateStar:T_Star()

' Constructor with Name, Pos, Vel, Colour, Mass
Function CreateStarNPVCM:T_Star(name:string, ...)

' Constructor with everything
Function CreateStarNPVCMRRR:T_Star(name:string, ...)

This is the area in which BlitzMax is weakest as a language with OO aspirations.


Koriolis(Posted 2005) [#10]
b) Derived functions that can return compatible derived types
Last time I checked it did, which was a good surprise. I think your problem in your example is due to the parameter list, not the return type. So it's again related to a lack of overloading, not the inability to have overriden methods return different types.

For (a), while it would clearly be nice, it isn't mandatory (it's usefull but not that much more than for any function, the constructor is not so special here).

BTW, overloading has close to nothing to do with OO. You can have it in non OOP languages, and (as in BlitzMax, but it's no the only one) you can have OOP languages without it.

The arguments for overloading are clear. Arguments against include the ambiguity problem (which one to call when more than one compatible overload is found). I would argue here that a solution might be to completly remove ambiguity by always disallowing for 2 overloads to have corresponding parameters (parameters at the same position in the parameter list) that are implicitely convertible from one the the other. The other alternative (chosing the 'best' overload when possible like in C++) would be too muech of a mess.


What lacks more is some acces restrictions at the function/method level. If the client 'MyType' should always call MyType.Create, there is currently no way to enforce it and prevent the direct call to the New AFAIK.


FlameDuck(Posted 2005) [#11]
A Simple Factory Pattern returns an instance of one of several classes depending upon the parameters passed to the factory method, which is something that constructors alone cannot do.
That's an Abstract Factory Pattern. I don't believe several classes is a requirement, but I don't have any books here to check it.


PGF(Posted 2005) [#12]
Koriolis,

You might be right about b) being a result of a) but either way many pains in BlitzMax would be solved by allowing method overloading.

I struggle to think of a non OO language that provides method overloading nor one apart from BlitzMax that is OO and fails to provide it. You must have some examples in mind ?

Seems to me that objects (contain data and code), inheritence (one thing is a more specialised version of another with possible new data and code) and polymorphism (an object reference can be the base type or something derived from it) concepts follow each other naturally. This is surely the heart of OO.

The desire for overloading arises directly as a productivity requirement from inheritence. Even better if it is supported in the IDE then you get all of the variations of a method at your fingertips.

I just don't agree that choosing a method among overloaded alternatives leads to too much of a mess. Lots of mainstream languages do it (C++, Java, C#, Visual Basic). Lots of people have no problem with it and more to the point would complain bitterly if it was taken away.

And if it is an issue then do what I said. Require an exact type match for each parameter so there is no possible ambiguity. This may require explicit casting but so be it.

I agree with wanting access restrictions. You'll notice that in my 'ideal' last example it is a true constructor method rather than a factory function. Even better if you could then hide the default constructor like:

private Method New()

So that it cannot be invoked.


octothorpe(Posted 2005) [#13]
That's an Abstract Factory Pattern. I don't believe several classes is a requirement, but I don't have any books here to check it.


No it isn't. An Abstract Factory is one level of abstraction higher than the Simple Factory - it returns one of several factories (simple or abstract.) When in doubt, or books without, Google.

The kludge feeling would be reduced if you BlitzMax implemented


No it wouldn't. Using a method as a constructor simply to get initialization of member variables is still a kludge, with or without overloading.


Koriolis(Posted 2005) [#14]
@Flameduck: octothorpe is right, it's factory not an abstract factory.

No it wouldn't. Using a method as a constructor simply to get initialization of member variables is still a kludge, with or without overloading.
I tend to disagree here. More precisely I'd say that not being able to have different constructors, with parameters, is a bit annoying, but named constructors in itself is not really a bad thing.


Seems to me that objects (contain data and code), inheritence (one thing is a more specialised version of another with possible new data and code) and polymorphism (an object reference can be the base type or something derived from it) concepts follow each other naturally. This is surely the heart of OO.
I agree, but overloading is an implementation of static, compile-time polymorphism, and that's till something pretty different from what you have listed here.

I just don't agree that choosing a method among overloaded alternatives leads to too much of a mess.
Depends. There are 2 issues: the mess that can arise for the language user (and it really can exist, especially when combining overriding and overloading). And the mess for compiler writer (features that have a direct impact on the typing system should be added very carefully).

The core problem is that overloading and overriding are 2 orthogonal issue, with one being resolved at compile time and on at runtime. You're mentionaing C++, and C++ is precisely the language where I think the problem is most obvious. But certainly in a language with a cleaner and simpler design such as BlitzMax, the problem could tend to be almost not significant. *Maybe*

Note that in case I was being unclear, I am not advocating against overloading, far from it.