Rae graphics hello

Long time no post.

Well, to put it short: things happened, decided to switch fields from video editing and colour grading into my wonderful hobby: programming, I got an internship at a programming company, got my first real programming job, lost that job, got my second programming job in less than a month after that, and I’ve been happily programming ever since.

Enough about me. What I really want to talk about is the Rae programming language. And a small graphics hello.

Last year I actually already got a working opengl window working with some cubes written mostly in Rae, with some glue code in C++. Here’s the link. (But that example is very old, and so is the Rae compiler in Github…)

Today I read the first pages of Peter Shirley’s (possibly small) ebook Ray Tracing in One Weekend. I haven’t bought it yet, but just bumped on it in reddit (and actually the Ray Tracing: The Next Week, which was free today…)

Anyway, it had a nice piece of graphics helloworld code which I wanted to try out in Rae. So, here’s the Rae code for Shirley’s graphics helloworld:

func main
{
    int nx = 1000
    int ny = 500
    log_s("P3\n", nx, " ", ny, "\n255\n")
    loop (int j = ny-1; j >= 0; --j)
    {
        loop (int i = 0; i < nx; ++i)
        {
            float r = cast[float](i) / cast[float](nx)
            float g = cast[float](j) / cast[float](ny)
            float b = 0.2f
            int ir = cast[int](255.99f * r)
            int ig = cast[int](255.99f * g)
            int ib = cast[int](255.99f * b)
            log(ir, " ", ig, " ", ib)
        }
    }
}

And here’s what that code results in after I transpile it with raec and then compile the resulting C++ with GCC. And I also needed to pipe the output to a file in the command line: ./graphics_ppm > graphics_hello.ppm

graphics_hello

Let’s see if I can get this version pushed to Github at some point.

Advertisements

How to get both Alt keys to behave as Alt Gr does (Ubuntu 14.04, xkb) AND get dedicated keys for curly braces

Today I spend a ridiculously large amount of my time trying to find the answer to the above question.

This applies to Ubuntu 14.04 which uses XKB for the keyboard layout. And I’m using Gnome 3.

The answer was finally found when I checked the file called /usr/share/X11/xkb/symbols/level3.

Well. I’ll just skip this. I don’t really have time to write this post.

For me the file to edit is this:


sudo gedit /usr/share/X11/xkb/symbols/fi

That’s the finnish layout. But there’s many layouts inside it.

I added a new layout, but you could maybe just edit an existing one.

Here’s the addition:

partial alphanumeric_keys
xkb_symbols "coding" {

    // Finnish keyboard layout with coding enhancements, no dead keys

    include "fi(fi)"

    name[Group1]="Finnish (coding)";

    key <TLDE> { [  at,              onehalf,          section,               NoSymbol              ] };
    key <AE11> { [  braceleft,       question,         backslash,             questiondown          ] };
    key <AE12> { [  braceright,      grave,            cedilla,               ogonek                ] };
    key <AD12> { [  plus,            asciicircum,      asciitilde,            caron                 ] };
    key <AC09> { [  l,               L,                l,                     L                     ] };
    key <BKSL> { [  apostrophe,      asterisk,         caron,                 breve                 ] };
    key <AB08> { [  comma,           semicolon,        cedilla,               ogonek                ] };
    key <AB10> { [  minus,           underscore,       hyphen,                macron                ] };
   
    include "level3(alt_switch)"
};

If you only want ALT thing and not the curly brace thing (and still want dead keys), then remove all those lines starting with key!SOMEKEY! from the above. And only relevant lines for {} are AE11 and AE12, braceleft, braceright. The other lines are just copied from the no-dead-keys version.

Then you must add this new layout to

sudo gedit /usr/share/X11/xkb/rules/evdev.xml

Find your layout. I searched for “Finnish” and added this variant:

coding
Finnish (coding)

Then update with:

sudo dpkg-reconfigure xkb-data

Change your layout from Gnome3’s upper right menu. Test. If it doesn’t work yet, log out. Good luck.

———————————————–

Other things to do:

Fix Command key (currently behaving as the Win key) to behave as Ctrl from the tweak settings (gnome-tweak-tool) or whatever that is.
(Translated from finnish it’s the setting under “Writing”, “Alt- and Win-keys settings” -> “Ctrl is set to Win-keys (and regular Ctrl-keys)”.)
You can fix Command+Tab from the keyboard shortcuts settings. Find Alt+Tab (or Super+Tab) and set it to Ctrl+Tab.

Linux would really need a visionary distro, that could fix computing to some sane defaults (for Mac users and other sane users). And if that is not possible, there should be easy to use GUI programs that could handle e.g. creating custom keyboard layouts. I found one python program from 2008, but as it was not included in any ubuntu repos, my guess is that it is not good enough. There’s a great program for OS X called Ukelele.

All I need:
– Gnome 3, with Nemo file manager or better. (Nautilus is the worst file manager of the decade. Ubuntu’s Unity is the worst desktop environment of the decade.)
– Close, minimize, maximize on the left side of the window. And I need all of them, not just close.
– Round window corners
– Both Alts do the same thing (The thing that the strange concept of Alt Gr does now.)
– Fix numlock. If I have a laptop that has an external keyboard connected to it, and want to use the numpad on it. Numlock behaviour is just broken, because if the need is: “I want all the keys to work on both my keyboards”, then Numlock in Ubuntu with a laptop, just isn’t the answer to this question.

Static arrays syntax

After my previous post about the perfect vector/array syntax, I’ve been wondering about static arrays. That means fixed-size arrays that are usually allocated on the stack.

Currently I’m leaning on the following syntax for vectors (dynamically resizable arrays):

[Tester] testers

So what about those static arrays? Maybe something like:

[Tester, 4] testers

Hmm. Is that pretty or is that ugly? I don’t know…

One option would be to do what D programming language does:

//dynamic arrays:
Tester[] testers
//static arrays:
Tester[4] testers

That surely looks more familiar and traditional. But is it really any better? And is there a reason to change it? The freshness of the newer syntax? All the lines of D code, that I’ll have to rewrite with the new array syntax? But now I’m forgetting my previous posts arguments that led to this new syntax in the first place:
Rae has “opt” and “val” and “link” storage/type specifiers which affect what properties a “reference” has. When we do something like:

protected opt Tester[] testers

It is not clear what that opt refers to. That’s why our arrays also need to be prefix rather than postfix.

So, again, maybe this could still be the best syntax for Rae:

//values are default now: val[val Tester] testers
[Tester] testers
//so, static array: val[val Tester, 4] testers would be:
[Tester, 4] testers
//link to a static array containing values:
link[Tester, 4] testers
//and the most dynamic of all arrays,
//the optionally existing resizable array of optional objects: 
opt[opt Tester] maybeTesters

P.S.
How about for loops then:

for(ref Tester a_tester, testers)
{
  a_tester.doSomething
}

And should that “ref” be automatic for function arguments and foreach loops such as this one. So you’d only have to define it for arrays of opts (use link to traverse it) or arrays of links (again use link to traverse).

Choosing the perfect array/vector syntax… Vote in the comments!

In the Rae programming language arrays are going to be implemented using C++ std::vectors. And I’m also thinking of implementing static arrays as std::array, but I’d like them to have the same syntax, and be interchangeable in function arguments, so that requires some more thought…

But what would be the perfect syntax for arrays?

As a reminder you create normal variables like this:

val SomeClass someObject
link SomeClass link_to_ob -> someObject
opt SomeClass someOptObject -> null

So the approach is to use more words and less special characters. But I might want to change this approach as it comes to arrays…

Here’s how arrays are created in the related languages:

vector<Tester> testers; //C++
vector<Tester*> testers; //C++
vector!(Tester) testers; //D
Tester[] testers; //D
Tester testers[];
[Tester] testers //Swift and maybe some other languages...

And here are the candidates for Rae. Feel free to propose more.

array val Tester testers

arr val Tester testers

vec val Tester testers	

vec[val Tester] testers

vec(val Tester) testers
	
[val Tester] testers
	
val Tester[] testers

Vote for your favourite in the comments. 🙂

Somehow, even though otherwise we are using words, the words start to clutter things pretty fast. If we’d want a protected optional array which holds objects by value, we’d write:

protected opt vec val Tester testers

And that would pretty much hide the “vec” and the fact that we have an array. Syntax highlighting might help there, but it still would be hidden.

For some reason I really like brackets in array syntaxes. So currently I think this looks the best, and it neatly looks sort of like a template too:

[val Tester] testers

And it is easy to parse, because the first character in the line is a bracket, so we’re waiting for an array.

So, continuing that thought the [] would implicitly be

val vec[val Tester] testers
//and a link to an array would be:
link [val Tester] linkToArray

And templates would then implicitly be usually val, unless stated otherwise.
//A related note: template syntax with brackets?

vector[Tester] testers
signal[void, int, float] mouseClicked
//But signals deserve a better syntax.

But this “implicitly val” leads to the question, shouldn’t everything be implicitly val? Then we’d really be close to C++ like in our original example of Rae syntax:

SomeClass someObject
link SomeClass link_to_ob -> someObject
opt SomeClass someOptObject -> null

//And our array syntax for value array 
//with value types would be just like in Swift:
[Tester] testers

It is slightly more painfull to parse, as the joy of declaring everything with reserved words beforehand, makes parsing so easy. But maybe I could manage with this syntax…

Any thoughts? Any readers? 🙂

Why do we set pointers with the assignment = operator? Shouldn’t it just copy?

In C++ the assignment operator is a bit strange regarding pointers. I admit that C++’s pointers are very value oriented, but anyway it seems strange to point pointers to objects with the assignment operator (=).

Tester tester_val
Tester* tester_ptr

//value copy
tester_val = *tester_ptr;
//set pointer to object
tester_ptr = &tester_val;

And other members of the language family (Java, C#) have the same problem, and in fact, it is even worse with those two, as a reference and assigning it with the = operator is the default case. (But in C++ you can use value types, and in C# structs…)
I just checked and the web is filled with beginner programmers strugling with these concepts.

So, in my opininion, a language should have a separate assignment (e.g. copying) operator and a separate set pointer (or reference) operator.

Let’s see how it would look in Rae code:

If we’d have a value type object and a link (a non owning reference):

val Tester tester_val
link Tester tester_lnk

Assignment (or copy) operator

tester_lnk = tester_val //segfault because we're trying to copy by value to null.

Actually we’d need to ? it because links are optionals too. So the former shouldn’t even compile. So the correct line would be something like:

tester_lnk? = tester_val

But that will still not run, because link is null currently. 🙂

And a set reference operator could be one of these (or propose a better one in the comments!):

tester_lnk -> tester_val
tester_lnk @ tester_val
tester_lnk @= tester_val
tester_lnk -@ tester_val
tester_lnk +@ tester_val
tester_lnk =& tester_val
//Hmm. This looks familiar.
//Hey that's C++!! Like this:
tester_ptr = &tester_val

I personally think the nicest one of these is the -> as it is instantly recognizable as the “point to” -operator. The bad part is, that it looks like the C++ pointer dereference operator, but since we’re not using it anywhere else, it doesn’t matter.

Let’s look at it one more time, to see if it really looks good or not (as the code is going to get filled with these).

val Tester tester_val
link Tester tester_lnk -> tester_val

What do you think.

P.S. This change also needs another change. The compare references operator. Which is “==” (in C++, Java) and “is” in D. So we could use one of the following:

if( tester_lnk <-> another_lnk )
if( tester_lnk <=> another_lnk ) //looks too similar to <=
if( tester_lnk @ another_lnk )
if( tester_lnk is another_lnk ) //ok, but doesn't look like an operator.

P.P.S. Hmm. A counter argument to this reasoning is this:
We are already removing the already mentioned pointer dereferencing operator

some_ptr->callSomething()

, and just using the dot

some_ptr.callSomething()

everywhere.
We are doing this so that we could just easily change from a pointer type to a value type when needed, without having to replace all our

->

with dots.

So, how does changing the assignment to mean kind of like the same thing with pointers and values affect this code reuse? And the fact that we’ll be mostly using opts and links anyway, which need to be

if(tester_opt)

or

tester_opt?.callSomething()

anyway, if we want to use them. So doesn’t

//Can we get this to show:
?.

serve the same purpose as

->

, but it just isn’t enforced in any way on compile time in C++???

Language design is interesting.

Starting git and github

I did not proof read this post! 🙂

I finally started using git again.

I tried using it some five years ago, but it was so user hostile, that I soon quit. First days using it were ok, but I had a few months break and didn’t remember anything, and so I eventually just gave up.
Now it’s time for another try. It seems the documentation is much better now, and there’s many more sites using it, than five years ago.

Git has one of the most user unfriendly interfaces of all time. It is inconsistent. But I’ll try to use it anyway.

There are probably great tutorials somewhere, and this is not one of them. I didn’t read a tutorial. I just googled every step. That’s why I ran into (small) trouble.

I first created an account for github some months ago. There are also other sites offering similar services. None of them are actually needed to use git, but it makes it easier when you can push your code to some external service and have it stored there.

Then I created a repository. Just a few clicks. Choose licence. MIT. It might have been a good idea to add a .gitignore file, but as the user interface for that wasn’t so clear, and I didn’t know what that was at the time, I did it later, and it was still easy.

Ok. So the trouble came when I did my first push. It had a wrong user name. It actually had the username of my computer account, which is just silly.

Here’s some quick notes what I should have done:

1. Cloned the repository from github to my local computer with:

git clone https://github.com/jonaskivi/rae_programming_language.git

It creates a new dir with the project name, so you don’t have to create a dir beforehand.

2. I should have created a .gitignore file at this point to ignore hidden OS X files. Such as .DS_Store.
Check to see if you have it already with listing all the files:

ls -a

Create the file like this (or edit it if you already have it). echo used together with > will output the text “.DS_Store” into the file .gitignore, which is then also created.

echo .DS_Store &gt; .gitignore

You can also create it with a text editor, but I liked the above solution. I should really try to actually learn the command line. But not vim. Never vim. Today I learned how to quit vim!

3. I should have changed my author name and email. But nobody told me to do it. Here’s how. Change yourgithubusername to your github username.

git config --global user.email "yourgithubusername@users.noreply.github.com"
#inside your git dir, just in case, and if you need different emails for different projects.
git config user.email "yourgithubusername@users.noreply.github.com"
git config user.mail
#OUTPUTS nothing on my machine. Even though the internet says it should.
#instead I checked it with the following (~/ is you home dir.)
cat ~/.gitconfig
#OUTPUT: [user]
#OUTPUT: 	email = yourgithubusername@users.noreply.github.com

4. I should have changed default git editor from vim to nano. Nano has onscreen documentation. Vim does NOT.

git config --global core.editor "nano"

5. I copied all the files and directories that I wanted to be in this repository. With a file manager or however you want to do it.

6. Add all the files with

git add .

7. Check what’s happening with

git status

8. If there are files that shouldn’t be there. I did this. There could be some better commands with HEAD in them.

git rm rae_compiler/rae_compiler/.DS_Store 
#OUTPUT: error: the following file has changes staged in the index:
#OUTPUT:     rae_compiler/rae_compiler/.DS_Store
#OUTPUT: (use --cached to keep the file, or -f to force removal)
git rm -f rae_compiler/rae_compiler/.DS_Store 
#OUTPUT: rm 'rae_compiler/rae_compiler/.DS_Store'

So I had to use the -f flag to force it. I don’t like to force things.

9. Commit to your local git master branch thing.

git commit -m "Added ugly compiler code."

10. To push to github. (Only works if you cloned from there. If you didn’t, you’ll somehow need to link it.)

git push origin master

——————————————————————————-

11. If you forget the -m message thing, you can quit vim by hitting the escape-key on your keyboard, and typing “:q!” to quit without saving.

12. If you’ve already made the mistake of not changing your author. Here’s how to destructively change history. Don’t do it if this is not your project, or something. I didn’t understand the script on github. This one I could understand. Franz Kafka is the old false author name I had.

git filter-branch --commit-filter '
         if [ "$GIT_COMMITTER_NAME" = "Franz Kafka" ];
         then
                 GIT_COMMITTER_NAME="your_new_name";
                 GIT_AUTHOR_NAME="your_new_name";
                 GIT_COMMITTER_EMAIL="your_new_name@users.noreply.github.com";
                 GIT_AUTHOR_EMAIL="your_new_name@users.noreply.github.com";
                 git commit-tree "$@";
         else
                 git commit-tree "$@";
         fi' HEAD

And then tried:

git push origin master
To https://github.com/jonaskivi/rae_programming_language.git
 ! [rejected]        master -&gt; master (non-fast-forward)
error: failed to push some refs to 'https://github.com/jonaskivi/rae_programming_language.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Rejection feels so bad sometimes.

I did “git pull”. It asked me about the message. But I had the Vim default editor. I googled how to quit it! Hit “escape key” and type “:q!” to quit without saving.

git pull

Probably you can put the message in there with -m. Didn’t try it yet.

#OUTPUT: error: There was a problem with the editor 'vi'.
#OUTPUT: Not committing merge; use 'git commit' to complete the merge.

Maybe it was my/vims fault that it didn’t merge.

git commit -m"Trying to fix git author :("

Committed the merge for me.

git push origin master

Pushed it to github. And my name was hopefully fixed, but I’m not sure. The old name still shows up in Github commits though.

End of post. Hope you found what you were looking for.

Two uses for “ref” or another “own” keyword?

My last post was about the supposedly perfect types for a new programming language.

I think I might be onto something here. But I also could be way off.

I personally think that owning pointers and optional/maybe pointers could be much more important than const correctness ever was. Well, if you have a garbage collector, then it’s not that much of an issue, but as I’m talking about something like C++ and manual memory management here, it is a very important thing for bug free code. I bet Rust has the perfect solutions for both of these issues (pointer lifetimes and const correctness), but it seems to be a moving target, and for some reason, I found it a bit confusing. (But I am a very confused programmer: that’s why I’m looking for clarity and simplicity.)

Ok. Let’s get to the details:

val SomeClass someObject

That was a value type.

ref SomeClass someRefObject

Basically a unique_ptr. But you can have links to it. You can’t delete it. It must always exist. You can’t pass it onto another thread. (I haven’t thought about concurrency much.) This must also mean, that you can’t have an opt pointer to it, only a link pointer.

link SomeClass someLink = someRefObject

That’s a link. The rule is: you can’t delete it. It’s just a link. You must check that it exists. So it’s just like an opt, except you can’t new it or delete it. It is just a link to something that exists elsewhere (or doesn’t exist).

opt SomeClass someOpt = null

That is an opt. You can new and delete as much as you want. It is versatile, but leads to having to always check if it is null or not. You can’t dereference it unless you check. So if you want cleaner code, you can use mostly refs and values, if possible. You’ll have to declare it null, if you really want it to be empty.

someOpt?.callSomeFunc

Thank you goes to Apples Swift for this nice syntax. This equals:
if(someOpt) someOpt.callSomeFunc, but it is shorter!

My question today is about the ref type. The sort of unique_ptr or sort of like C++ pass as reference. I’m wondering if it would be more clear to use two keywords or just one keyword with it.
The two use cases are:
1. real refs who actually own their data. Usually members of a class.
2. function arguments passed as refs, who are only guaranteed to not be null, but don’t actually own their data.

Should they both use the keyword “ref”. Or should the first one be “own”, like here:

own SomeClass someOwnObject

func ()someFunc(ref SomeClass someArg, int val_arg)
{
	//delete someArg //can't delete someArg
	//someArg is guaranteed to be always valid.
	someArg.callMe
	//opt myFavouriteOpt = someArg
	//can't pass it onto opt, because then you could delete it!
	
	link butICanLinkToIt = someArg

	butICanLinkToIt?.callMe //and then you must check for it
}

someFunc(someOwnObject, someOtherOwnObject, 42)

//OR should they both just use ref

ref SomeClass someOwnObject
func ()someFunc(ref SomeClass someArg, int val_arg)
{
	//... the same
}

So, which one is more confusing. A new keyword, or overloading the ref keyword to mean two related concepts, that for the most part share the same properties? “ref” keyword would then just quarantee that the pointer exists.

I’m currently opting for just a single “ref” keyword for both cases, but I really like the own keyword too. But it sounds more like a verb than a type.

I think the most important type here is “link”. Because it can hold anything. It can hold opts and refs.

I thought I’d make a sort of a list of the qualities of each type, and how they are connected:

link = ref //ok
link = opt //ok
link = link //ok
link = val //ok
new link //not allowed
delete link //not allowed

opt = link //not allowed, because it could be a ref.
opt = ref //not allowed. Use a link instead.
opt = opt //ok
opt = val //not allowed. Use a link instead.
new opt //ok
delete opt //ok

ref = link //not allowed, except as function args (own keyword?)
ref = opt //not allowed, except as function args
ref = ref //not allowed, except as function args
ref = val //not allowed, except as function args
return move ref //ok. C++ move semantics, but only when returning refs.
new ref //ok, when initializing
delete ref //not allowed. It behaves like a value type.

Why do we need “own”s. Why do we need them? Why do we need unique_ptr’s?
Can’t we just use “val”s to own data. links to link to them safely. refs as function arguments that are guaranteed to exist. And opt’s when we want to make it null or to exist. That would be closer to C++…

I’ll have to think about a use case for “own”.

The ?perfect? types for a programming language

The perfect types for a programming language could be:
val
ref
opt
link
ptr

Here’s why:

I’m trying to hack up a little programming language called Rae.

While thinking for it a while, and skimming through the awesome new book called Game Programming Patterns and it’s chapter on data locality
I came to think that C++ and C has a great use for it’s stack allocated value types: speed.

If I haven’t completely misunderstood the concept, array traversal is much faster when your data is contiguous. If you use pointers or other type of references in many languages, your program will jump between different areas of memory while going through your array of objects. But when you use an array with value types, your data is supposed to be contiguous in C++. This will make your program run faster.

So we want value types. These will be marked with the keyword “val”.

But using value types as function arguments is slow, if the objects are slow, because you’ll have to make a copy of the whole object. Therefore you can use a pointer or even better, a C++ reference. But the notation and the rules are a bit unintuitive, in my opinion. In Java it is nice that function/method arguments are (Java) references, as all Objects are anyway. So Java syntax is nice here (except it is dull to be always checking for null in almost all cases.)

So we want reference or pointer type for function arguments. And for dynamic memory too. These will mostly be marked with the ref keyword.

But we don’t want pointer math for our basic references. That’s why they will be called references, and not pointers. But we’ll still have traditional pointers. (Maybe you’d need to make an unsafe{} area to use them…)

Owning and borrowing is an interesting concept in the Rust programming language. I’ve only very superficially looked at Rust, but it all seems a bit complicated to me. I’d want a bit more flexibility, and a clearer syntax, with less special grammar like ~, @, and even * and & in C++. So we’ll use words, even if it costs some more keystrokes. At least we’ll use shortened words (I believe the word is abbreviations in english!).

But we’ll make it so that a value type of course owns it’s data. I just checked that in C++11 you can use “move” to put a value type into a container (like a vector) without copying it, thus transferring the ownership. This was the thing that always made me avoid value types – being afraid of the copies. And you can also use e.g. vector.emplace() to create an object directly inside the vector. That sounds so great.

I also checked out half of the video on “null being the billion dollar mistake”. So I thought it might be usefull to never default on null. And to have a reference type that is never null (C++ kind of has this, but in a restricted way). And then we’d still like to have a “maybe” or “option” type that can be null, but must be checked before use. The maybe/option type can own memory (owner is usually the creator).
The keyword for a maybe or option would be “opt”.

On borrowing I thought we could make a “link” type reference, which can not own memory. It can be null, so must be checked every time, but it can not destroy memory either, only link to it.

So. Here is the proposed type system that could be good in my opinion. Please comment if you think otherwise, or have better suggestions.

//built in types are value types.
//int, uint, long, float, char, etc. and also string, default to value type.
int someInt
float a_float
string the_string

Button button //defaults to ref on objects.
val Button button_val
//value type. Owns static data on the stack.
ref Button button_ref
//reference. Can not be null. Very similar to value type.
//Use it mostly in function arguments. Owns dynamic data on the heap.

opt Button button_ref
//maybe owns data. null if doesn't own it.
//The only type that you can delete/free dynamic memory.
//But you must always check for null before using it.
//Compiler won't let you use it if you don't check.

link Button button_lnk
//links to data, can't delete it. only borrows data.

unsafe
{
ptr Button button
//C++ pointer. If you need it. Maybe need to use it inside unsafe block.
}

//Call a member or function always with a dot like in D:
button_val.callMe
button_ref.callMe
button_ptr.callMe
//etc.

//dynamic arrays. Internally implemented as std::vectors,
//so we can know their size.
val Button[] buttons_val //in C++: std::vector buttons_val;
ref Button[] buttons_ref //in C++: std::vector buttons_ref;
opt Button[] buttons_opt //in C++: the same as above.

buttons_val.push_back( button_val ) //copies
buttons_val.emplace //creates a new Button by value.

//static arrays. Internally implemented as std::array or boost::array,
//so we can know their size.
val Button[100] buttons
ref Button[100] buttons
opt Button[100] buttons

//C arrays
ptr Button = new val Button[100];

Ok. That’s it. Any comments are much appreciated!

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!