Game Programming Language! (Gamma)

Well here I am again, wanting to make another programming languange (Gamma). Why? You might ask. All I can say is, I really want to. I love creating little applications, testing out ideas, and prototyping different concepts. I could always use LibGDX, Unity, or some other engine or library that already exists; I don't want to. I want to be in control of how the language looks, compiles, and acts. If I want to add a special feature in the language that doesn't exist in C++, I want to be able to; not just create a library, but make the functionality actually part of the language.

Simplicity over speed

Due to the nature of this language, I am deciding early that, Simplicity is more important than Speed. If I can express something in the language simply and slower or complicated and faster, I will choose simplicity (To an extent of course). The primary example here is going to be Pointers and Memory Management. While I am in favor of raw pointers, for their blinding speed, they do not offer security, and consume some brain cycles to use. In contrast to References (Such as in PHP), which are simpler to use. I am not saying I am going to use PHP's reference system, but I am thinking about how simple it is. And in all actuality, I think I might use a Deterministic Garbage Collector or Reference Counted Pointers or a Mix of both.

Language Patterns

To my knowledge there is no such thing as a "Language Pattern" or at least it probably doesn't mean what I am using it for. By Language Patterns, I mean that the Language will contain the features of common Design Patterns which you normally find as Libraries in languages such as C++. This can be seen in other languages such as C#. Where you have a Pub/Sub or Observer like pattern baked into the language itself with Events and Delegates. This is exactly what I mean by Language Patterns! In game development there are specific patterns that are used regularly for example MessageQueue, Singleton(?), Prototype, Iterator, Visitor, Command(?), Component and some others. The idea is to bring these into the language directly, simplifying the usage of the patterns and hopefully speeding up the development of the prototypes.

I would like to mention that this language will be targeting good ol' C99 (I think). This means that these features will actually translate into code that is not always or hardly ever a 1:1 mapping from Gamma to C. Most of these features will end up being utilization of a library that I write, which you might think of as a Language Runtime. Similar to C++ Runtime (Which we wont need as we will be transpiling to C)

Language Types

I want the Type System to be very robust. I want to have minimal types, but offer as much flexibility as possible. The language is Type Oriented (not really OOP) mostly, with the exception that it will support Mixins (CompileTime) and FunctionBinding (Runtime)

Mixins?

As you might know in Scripting Languages such as PHP (Traits), Lua via OOP Libraries (Mixins), and possibly others; but NOT like D Mixins. Gamma Mixins is a simple way to create an Interface like definition however, instead of just declaring an interface, you can define the functionality in the Mixin, including ObjectState (local variables). At compile time Gamma will inline the functions and the variables into the class you have defined. Mixins are a compile time only feature for code organization. While they are immutable at runtime, they will have metadata added to the RunTime-Type-Interface (RTTI). This will be useful for cases where you want to ask if a specific object is of a Mixin at runtime. This is not limited to runtime, you might want to create a list of a certain Mixin similar to Interfaces, which are not of the same Class. This is completely possible and is a good use for Mixins. They should replace Interfaces (Which do not exist in Gamma) in all use cases.

FunctionBinding?

FunctionBinding is what I am calling this for a lack of better term. Basically, you are able to bind a function to an object or type at runtime, and compile time. I am not sure why this is useful at runtime yet, but I would like to play around with it and see how it goes.

Language Syntax

I have absolutely no clue what I want the syntax to look like yet. I am thinking it should be easy and familiar, but at the same time I want it to be a little different. I want you to know when you look at the code that it isn't C, C++, VB, Pascal, C#, Java, or even other languages such as Haskel or SML. Given that I want a whole slew of language features that other languages don't have, I have a feeling that I might over complicate the language grammar.

module main;

import std; # Example of a standard import
import string_utils as ::; # Import into current namespace
# Namespacing is scoped, meaning if you pull libs into a local scope
# they do not affect the namespace outside of the scope of the import.
# This also means that you can current namespace in scope and not
# clutter the module's namespace or global namespace

fun main() -> Int32 {
    
    0; # Return 0 for exit
}

# Simple nested functions calls
string name = "Donald Duvall";
string firstName = to_upper(split(name, " ")[0]);

# Same thing using pass-forward function calls
firstName = split(name, " ")[0]->to_upper();

# This can even be written
firstName = name->split(" ")[0]->to_upper();

###
This works as syntactic sugar almost, but it is not the same resulting
op codes actually. The result of the call is passed to the first argument
of the following request.

This is a little different than OOP style chained functions, which are
calling methods of the resulting object.
###


###
Classes & OOP?
  All types in Gamma are more like structs and do not contains methods.
  It is also worth noting that there is no way to require a Reference type
  and there is no need to. References are always defined at call time
###
type Component {
    _id : Uint32;
}
construct() Component { 
    # static function variables are globally initialized but only
    # locally accessible. They do not free until the application
    # exits, and retain their value between calls
    # Initialization is guaranteed to execute only once 
    lastId : static Uint32 = 0;
    lastId++;
    self._id = lastId;
}
fun render() Component {}
fun update(dt : Float) Component {}


type ComponentManager {
    _components : Component[];
}

fun render() ComponentManager {
    for comp in self._components { comp.render(); }
}

fun update(dt : Float) ComponentManager {
    for comp in self._components { comp.update(dt); }
}

type Actor {
    _id : Uint32;
    mixin ComponentManager as ::;
    mixin MessageQueue as queue;
}

construct() Actor {
    lastId : static Uint32 = 0;
    
}

destruct() Actor {

}

# Defining the cloner
#    (Arguments)                                    Attach to type  Return type
clone(fromActor : Actor, addToScene : bool = false) Actor => Actor {
    import math as ::; #import the math lib into local scope and local namespace

    var actor : Actor = Actor.construct();

    for comp : Component in self._components {
        actor.add_component(comp.clone());
    }

    actor;  // The result of the last call is the return of the function
}

fun render() Actor {
    self.components.render();
}