Open B-rando1 opened 3 weeks ago
We discussed in our meeting today that it's ok if some design decisions don't work in all languages. Based on that, it seems to me that the right choice is to allow multiple constructors in GOOL, but have the Python renderer throw an error if we give it multiple constructors. This is in line with our treatment of floats (also not supported by Python).
As another side note, this is one more reason why #3763 is a useful change: counting the number of constructors!
Using the @classmethod
annotation on methods defined inside of classes is conventional for building alternative constructors in Python. Actually, those are technically named constructors, but reliant on a base library-provided annotation (arguably not a part of the language specification, but I don't really see it going anywhere...).
For example,
from math import cos, sin
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
@classmethod
def from_polar(c, radius, angle):
return c(radius * cos(angle), radius * sin(angle))
r, a = 10, 0
p = Point.from_polar(r, a)
This is relevant to our recent discussion about the constructors and methods.
Oh, that's interesting @balacij! I'm trying to think if there would be a way to take advantage of this functionality in GOOL.
@classmethod
annotation and it's called like a static method.Do we think this is a worthwhile change to make? Enabling named constructors in GOOL likely wouldn't be too big of a task (apart from a few discussions about semantics), but taking advantage of it in drasil-code
might be tricky.
I guess we can't call it a method, since it has the @classmethod annotation and it's called like a static method.
Yep, it is a class-level method (individual instances of the class do not have the @classmethods
defined within them)! One note: @staticmethod
differs from Python's @classmethod
in one 'real' way: a @classmethod
method has access to the class through the first parameter (i.e., self
, except self
refers to the class).
With our current structuring of constructors it would be difficult to make it work, as we would need to give a different name to each constructor. Getting unique names wouldn't be a problem, but keeping track of which name is used for each type signature would be.
Yep. This is really where we would need named constructors. Now that I think about it: I think that named constructors should be the default. They provide information about which constructor we really intended to call. Overloading can then be employed only when rendering into a language that supports it.
I suppose if we extended the functionality of constructors to allow named constructors (as you mentioned above and in our discussion of constructors and methods), we could probably make it work that way.
Yep!
Do we think this is a worthwhile change to make? Enabling named constructors in GOOL likely wouldn't be too big of a task (apart from a few discussions about semantics), but taking advantage of it in drasil-code might be tricky.
If it's not too much work on GOOL's side, I think it would be a great idea! Do we even have any instances of multiple constructors on the -code
side? It might be useful to only have it one-sided for now?
All of our languages except Python allow multiple constructors for an object. We should probably lay out a stance on whether GOOL allows multiple constructors.
As a side note, Julia encourages having constructors call other constructors (e.g. cascading up default values) when it makes sense. See here for an example. I don't think this idea works in other languages, so I'm assuming we don't need to worry about that in GOOL?