Rae PL – named function arguments and defaults?

Hello.

No feedback yet. Well, that’s understandable, as I’m just shouting to the internet in the middle of the night without telling anyone to come and listen.

Anyway. This is going to be my first question, and you get to directly influence the syntax of Rae programming language. All you have to do is answer the question in the comments.

C++ has something that I’d call function argument parameter defaults that only work when defining the class header. It’s awfully painful to strip all the defaults away when doing the implementation part into the .cpp file. And again when you’re calling the function (or method in C++-speak), you’re forced to strip away the argument types and names.

An example:

//in the class definition you might have a method:
int someMethod(int set_age = 45, int set_points = 0, int how_many_pianos = 1, Button* dont_push_this_button = 0, bool do_the_stuff = true, bool what_about_other_stuff = false, int nro_fish = 5, int nro_rodents = 0);

//and then in the .cpp implementation you'll have to strip the params and
//add the class name to every method.
int SomeClass::someMethod(int set_age, int set_points, int how_many_pianos, Button* dont_push_this_button, bool do_the_stuff, bool what_about_other_stuff, int nro_fish, int nro_rodents)
{
...
}

//Ok. And then you call the method later:
if(someObject) someObject->someMethod(47, 32, 2, myButton, false, true, 129, 62);

Wow. When I’d 2 years later read the function call, I’d be forced to look at the definition of someMethod, to see what are all those ints and bools doing, and what do they affect.
Ofcourse it is possible to write it as a comment, but that kind of duplicates the line.
Or then you do

someObject->someMethod(/*set_age:*/47, /*set_points:*/32, /*how_many_pianos*/2, /*dont_push_this_button*/myButton, /*do_the_stuff:*/false, /*what_about_other_stuff:*/true, /*nro_fish:*/129, /*nro_rodents:*/62);

But somehow that doesn’t look so pretty.

Also it really annoys me when I’m using my beloved copy-paste keyboard shortcuts, that I actually have to strip so much info out of the function definition just to call it.

In Rae I’m hoping we can change that. In Objective-C you can have named parameters in function calls like:

[someObject setAge:47 set_points:32 how_many_pianos:2 dont_push_this_button:myButton do_the_stuff:false what_about_other_stuff:true nro_fish:129 nro_rodents:62];

And that looks so much better than the C++ version. It is a self-documenting function call.

So, because Rae is still going to look more like C++, C, Java, D and the curly brace family, in Rae a function call is going to look something like this (also notice the included argument types in the function call):
option 1:

someObject.someMethod( int set_age = 45, int set_points = 0, int how_many_pianos = 1, Button dont_push_this_button = myButton, bool do_the_stuff = true, bool what_about_other_stuff = false, int nro_fish = 5, int nro_rodents = 0 );

or option 2:

someObject.someMethod( int set_age: 45, int set_points: 0, int how_many_pianos: 1, Button dont_push_this_button: myButton, bool do_the_stuff: true, bool what_about_other_stuff: false, int nro_fish: 5, int nro_rodents: 0 );

So, now you get to decide which one is it going to be! Tell me in the comments.

But which ever character is chosen (the equal sign or the colon), the function definition will still use the same way of defining the defaults. That way it will be just a copy paste when you want to use the function in it’s default form (in case all it’s arguments have default parameters…).

Here’s what that same definition would look like in Rae, if we took the Option 1.

func (int nro_bottles_i_have_to_drink) someMethod (int set_age = 45, int set_points = 0, int how_many_pianos = 1, Button dont_push_this_button = what_should_i_put_here_it_cant_be_null, bool do_the_stuff = true, bool what_about_other_stuff = false, int nro_fish = 5, int nro_rodents = 0)
{
...
}

I really love copy pasting the function definition and then just moving along without much editing. How does this sound to you?

Rae programming language – feedback appreciated!

I’ve recently started a half serious project of making my own little programming language.

The sort of a “compiler” I have now, is written in C++, and it’s just a little script that outputs (pretty readable) C++ code. It’s a bit like Lazy-C++, except I decided to “fix” the syntax while getting my one source file split into .hpp and .cpp files. So, if you want to see a real compiler, there’s nothing here to see. But, if you want to discuss a good syntax for a modern general purpose, high performance, manual memory managed language, then this is just the place!

So, the premise is that we want to replace C++, because we want a cleaner and nicer, more productive, and a little bit safer syntax.

I’ve tried D, but I didn’t like garbage collection (because it ruins performance when doing real time stuff, no matter what they’ll tell you.) There’s also Amber (a fork of D1), which seems nicer than D2, but I believe still has GC. Go and many other new languages all have garbage collection.

Rust looks promising, but to my eye, it looks a bit foreign and a bit complex. I want a simple language (like D1). But Rust has some very interesting ideas for memory safety and other stuff, that my poor head doesn’t even understand.

I also really like Objective-C features, but the syntax isn’t perfect.

So we want to take the performance of C++, the simplicity of D1, some memory safety ideas from Rust, and run with them. Oh, and for some reason, I’ve always wanted multiple return values in function definitions (somebody once told me MATLAB has them, should check that someday). And here’s a part where we’ll lose half of the audience: I want curly braces, but no semicolons. Ok, I’ll give you optional semicolons, so you’ll feel welcome.

Here’s a HelloWorld.rae, that I am able to compile with the buggy rae_compiler now.

module rae.examples.HelloWorld

class Tester
{
public:
	func ()logMe()
	{
		log_ln("Hello ")
	}
}


class HelloWorld
{
public:

	func ()new()
	{
	}
	
	func ()free()
	{
	}
	
	public func
	()sayHello()
	{
		tester.logMe
		log("World!")
	}
	
	func (int result) count (int param1, int param2) public
	{
		return(param1 + param2)
        //or you could just do: result = param1 + param2
	}
	
	int num = 5
	uint num25 = 4
	protected long anotherNumber = 42
	float afloat = 248.52
	double initMeToo
	int azero

	Tester tester /*this is a "reference". 
    Dynamically allocated automatically.
    unless, you specify it as "scope". 
    Then it will be like a value, but you still
    use it as a ref... Huh?*/

	//here's how you use vectors:

	protected vector!(Tester) testers

	func ()createNewTester() public
	{
		Tester atest
		testers.push_back(atest);
	}

	func ()logTesters() public
	{
		for(uint i = 0; i < testers.size(); i++)
		{
			testers[i].logMe
			log_ln("from tester: ")
			log(i)
			
		}
	}
	
}

func
(int) main (string[] args)
{
	HelloWorld hello; 
    //semicolons are allowed, but not required. 
    //And this is a ref = new that you'll have to .free()
	
    int val = 5
	int another_zero
	float i_want_to_be_zero

	if(hello)
	{
		hello.sayHello()
		log_ln("5 + 2 = ")	
		log(hello.count(int param1: hello.num, int param2:2))

		for(uint i = 0; i < 7; i++)
		{
			hello.createNewTester()
		}

		hello.logTesters
	}

	hello.free //Here we'll free our ref.

	return(0)
}

Ok, so half the stuff I mentioned earlier are still missing. No multiple return values there, no Rust inspired owning and borrowing of pointers. And no raw C-arrays yet. But we’ll come to those later.

I’ll make some more posts to detail some of those non-working ideas later.

The basic thing in this example is that just like in Java, the built-in-types are used like value types and user defined types (classes) are used as “references”/actually C++ pointers.
The references are automatically allocated when you define them.

Normal references can not be null, so they are more like C++ value types, except they are dynamic (by using vectors/arrays of objects.) I think we might have something like a nullref later.

SomeClass someObject
SomeClass? nullRef

Maybe this will have something to do with owning and borrowing?

Oh, and the multiple return values is going to look like this:

func
(int ret1, float ret2)doSomething(float param1, float param2, string param3)
{
        return(int ret1: 5, float ret2: 25.3)
}

Any comments will be appreciated!