Edit: my language allows for multiple inheritance, unlike Java.
I've started designing and developing my own programming language for educational, recreational, and potentially useful purposes.
At first, I've decided to base it off Java.
This implied that all the code would be written in form of classes, and that code compiles into classes, which are loaded by the VM.
However, I've excluded features such as interfaces and abstract classes, because I found no need for them. They seemed to be enforcing a paradigm, and I'd like my language not to do that. I wanted to keep the classes as the compilation unit though, because it seemed convenient to implement, familiar, and I just liked the idea.
Then I noticed that I'm basically left with a module system, where classes could be used either as "namespaces", providing constants and functions using the static
directive, or as templates for objects that need to be instantiated ("actual" purpose of classes in other languages).
Now I'm left wondering: what are the upsides and the downsides of having classes as compilation units?
Also, any general commentary on my design would be much appreciated. An informative post on my language can be found here: http://www.yannbane.com/2012/12/kava.html.
-
1If the classes also include namespaces that disambiguate all of the identifiers in the class, then you have a completely self-contained compilation unit. That class can be compiled successfully, provided all dependencies to other classes can be satisfied either by compilation or by reference to a compiled class in an assembly. Such atomicity should have obvious advantages.Robert Harvey– Robert Harvey12/18/2012 23:40:36Commented Dec 18, 2012 at 23:40
-
Side note: If you remove abstract classes and interfaces, you're forcing people to use inheritance for subtyping and polymorphism. That's bound to produce awful code. Also, unless you add multiple inheritance (and handle the associated problems), it's incredibly restricted.user7043– user704312/18/2012 23:42:05Commented Dec 18, 2012 at 23:42
-
1@delnan: Actually, you can still use composition to build up functionality.Robert Harvey– Robert Harvey12/18/2012 23:42:38Commented Dec 18, 2012 at 23:42
-
2@RobertHarvey I assume you're talking about restrictions by lack of multiple inheritance. Yes, one can emulate it with enough composition, but I'd hardly consider it acceptable. For example, an object that would usually implement two interfaces would have to be implemented twice, in subclasses of distinct base classes (and while both implementations could delegate to a common class, that's still a shitload of extra code and you can't easily turn an instance of one into an instance of the other).user7043– user704312/18/2012 23:49:14Commented Dec 18, 2012 at 23:49
-
@delnan: What's wrong with using inheritance for subtyping and polymorphism? That's what inheritance is for...Mason Wheeler– Mason Wheeler12/18/2012 23:50:16Commented Dec 18, 2012 at 23:50
2 Answers 2
what are the benefits of having classes as compilation units?
It can reduce the complexity of the language. No need for different constructs, everything is treated the same. In certain designs (though not yours it seems), you benefit from not having statics and the design issues they tend to run into (initialization order issues, concurrency limitations, awkwardness with generics/type classes). It also allows some benefits of the module concept like isolated module instances for sandboxing or parallelization; and module typing where dependencies fit some interface and the entire module worth of implementation can be instantiated and dropped in.
That said, the concept tends to have more issues than not. Realistically, you can't treat everything the same, since 'top level' classes need special rules like having a default constructor (or else you run into odd issues spinning them up). Modularity of compilation units tends to get really awkward too. How does a class even reference others when they're just classes? How are those dependencies dealt with, and how do you determine the correct order for spinning up the classes? How do you make sure that duplicate class references are reused by different parts of the app (or how do you deal with duplicate instances if that's the semantics you want)?
Having looked into it, I ran into a lot of issues with dependencies, scoping things properly, and initialization concerns. You end up running into issues that make 'top level classes' special, and many limitations to make them work that ends up shaping them into simple namespaces.
-
I plan only to have one single top level class, the
Object
. I realize that I'll probably need some special behavior for it, but as long as it's an isolated case, I'm OK with that. I don't believe I will have any dependency issues though. There's a set of classes that are loaded when the VM starts, some of them are implemented natively (the System class), but they all inherit from Object. Once everything has been loaded, the KVM loads the class it was instructed to load, and works out the dependencies. However, I'm interested, which problems do statics introduce?jcora– jcora12/19/2012 08:29:50Commented Dec 19, 2012 at 8:29 -
@yannbane - I don't mean
object
, I mean classes that are behaving like modules rather than inner classes that are not necessarily public outside of their compilation unit. 'Works out the dependencies' turns into a giant hornet's nest in the details if you want any sort of DLL style behavior; ymmv. As for static.Telastyn– Telastyn12/19/2012 12:43:46Commented Dec 19, 2012 at 12:43 -
That module-like behavior would be achieved through the use of static methods/variables, right? Is it bad to, instead of creating a class which can be instantiated, create a class which only has static members and methods? I saw that article, however, I don't think it applies to constant static members, nor static methods. For example, I see nothing wrong in creating a
Math
class, which is actually a module with static methods and a constant static double member calledPi
.jcora– jcora12/19/2012 22:19:40Commented Dec 19, 2012 at 22:19 -
@yannbane - No, not really. Modules are modules because they're instantiatable. Otherwise you just have C++ style namespaces. Once you limit your top level classes to be C++ style namespaces, they're not really classes anymore.Telastyn– Telastyn12/20/2012 00:20:57Commented Dec 20, 2012 at 0:20
-
Hm, I'm still OK and don't really see the problem with creating modules with classes. And yeah, modules do act as namespaces, especially Python modules.jcora– jcora12/20/2012 18:51:06Commented Dec 20, 2012 at 18:51
Instead of answering this question, I will go one level up and suggest studying the MIT OpenCourseWare, particularly 6.035 (Computer Language Engineering). This will explain the whole problematics, so that you will not get tempted to ask questions like this again.
Computer Language Engineering
The only pre-requisite is Java.
Course Description
This course analyzes issues associated with the implementation of higher-level programming languages. Topics covered include: fundamental concepts, functions, and structures of compilers, the interaction of theory and practice, and using tools in building software. The course includes a multi-person project on compiler design and implementation.
Explore related questions
See similar questions with these tags.