Computers are good at following instructions, but not at reading your mind.
- Donald Knuth
GreetLang+ does not exist, it is a concept.
It will be regularly expanded upon by me. Feel free to point out inconsistency issues, general problems,
and ideas.
Thank you, and enjoy the documentation of the GreetLang+ Programming Language!
============================================================================================
- 1. Basic Info
- 2. Gl+ Documentation Beginning
- 3. Introduction
- 4. Data Types
- 5. Basics
-- 5.1 Your First Program
-- 5.2 Running Our Program - 6. Variables
-- 6.1 Variable Names
-- 6.2 Adding Integer Variables Together
-- 6.3 Merging String Variables
-- 6.4 Short-hand Variable Names (Nicknames)
-- 6.4-1 Why Use Short-hand Variable Names?
-- 6.5 We're Done With Variables! - 7. If, Elif and Else
- 8. Loops (Chapter not written yet)
- 9. Input
- 10. Functions
-- 10.1 GreetLang vs GreetLang+ (a function comparison)
-- 10.2 Auto Functions (autofunc)
-- More Parts coming soon! - 11. Classes and Inheritance
-- 10.1 The Good Stuff
============================================================================================
Hey! Scroll past me to see the documentation!
(The reason some code has pictures and some does not is because this was undergoing a sort of revamp before it was abandoned.)
This is a revamped version of the concept generic use programming language, Greetlang
(otherwise known as Greet
), created by, me, of course. I have been very happy with my documentation over the language and all of my own "original" ideas. However, the key word is, original
. Very far into production of the language, I realised that most of my ideas had already been done by other people, and what especially surprised me, was the OFFICIAL Carbon-Language
actually had nearly the exact same ideas as GreetLang! The first instance of me discovering the similarities of GreetLang with other languages occured to me while trying out Rust, where I saw that you could specify the type of a variable if needed. I saw my code and thought,
Hey, that looks a lot like GreetLang!
I looked back at my code.
fn main() {
let mut x: i32 = 4; <-- Look here.
println!("x is: {}", x);
}
And back and my GreetLang.
let x: int = 6; <-- Look here,
let y: int = 7; <-- and here.
greet(x * 7);
If you can't see my point, look at the Rust code. When simplified it means let x: int = 4
.
When I investigated more and more into GL and it's features, I kept on finding unoriginal ideas. So GreetLang Plus
, is here to change that. Me personally, having spent so much work on that language, would like to pay it some justice after all my effort into essentially a harder version of Rust, C, and Python mixed together to vomit out some unoriginal ideas marketed as my own. I may be being a bit harsh on GreetLang, but I would like my language to be as original as possible (with some tried and tested elements from other languages, of course). GreetLang+ also aims to add a better syntax, new features, and a lot more. When I created GreetLang, I did not really have a good grasp on programming as a whole, let alone designing the languages you use to write code. So now that I've learned more about that, I think I'm ready to try again. Enjoy!
- Daniel C.
====================================================================================================
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
- Martin Fowler
Greetlang+ is a simple programming language that is designed to be easy to learn and use. It is a revamp of Greetlang, which adds several new features, as well as reworking the syntax to make it more intuitive and easy to read.
GL+ strives to be a syntactically sound language (which will probably never happen) that is fast, clean, easy to read and learn.
func stroutput() rt:userdef[]{
def var twelvify = varnix(22);
oxo int(;drax)-- 2B
;HEX%
;RBA
;TRANSFUGATE_ twelvify
;ULTIMIX = sevars drax[0P]
forargs="for" ox in(oxo)::multip 0x21432020;
using HEX% trans ;drax into type="str"
using "convert.gp" and twelvify:
namespace 23xB;;;
str _ == "H\ne\nl\nl\no\n \nw\no\nr\nl\d\n".charAt=11;
return str;
}
func st() rt:int[0]{
op(stroutput());
}
And they lived happily ever after. The End.
What’s this? You say something’s still not clear about this whole Greet
programming language thing?
Well, to be quite honest, I’m not even sure what the above code does (which says a lot since I created the language the program was written in). It’s a snippet from one of the cursed notes on my hard drive full of a wonderful collection of programs where I attempt to write the most unreadable GreetLang+
code possible, with often surprisingly cryptic results.
The bad news is that if you’re a beginner in this, all GreetLang+
code you see probably looks obfuscated! The good news is, it’s not going to be that way for long. That's why you're readng this, of course.
So if your eyes haven't already melted off from looking at that code, get ready for a non action-packed programming language documentation, because we’re going to don our heavy-duty rubber gloves, grab a scalpel, and rip into this thing to see what makes it tick!
Let's begin with data types. This will let you know to identify one of various types of data.
Greetlang+ supports the following data types:
string: A sequence of characters enclosed in quotes, e.g. "Hello, World!".
number: A numeric value, e.g. 42.
boolean: A value that is either true or false.
undefined: A value that is used to represent an uninitialized variable or an absent value.
GreetLang+ supports single line
and multi-line
comments.
Single line:
// Hey! This is a gl+ single line comment
Multi line:
/* I am a multi-line comment.
You can write across multiple lines,
and then end the comment like this -> */
Ah, behold the mighty semicolon (this little guy -> ;
)!
Yes, that tiny, unassuming character holds the power to prevent your entire program from going up in flames. It's like a little superhero that tells the compiler, "Hold on, take a breather, let's move on to the next line of code."
Remember, the semicolon is your loyal sidekick. It ensures that each line of code comes to a graceful conclusion before moving on. It's tthe punctuation mark that keeps everything in order!
__________________
| |
| I'm so cool! |
; < |
\__________________/
That you are, little bud, that you are.
Alright, alright! Now that you know the simple stuff, let's go into more detail in the Basics
of GreetLang+
The computer programmer is a creator of universes for which he alone is responsible. Universes of virtually unlimited complexity can be created in the form of computer programs.
- Joseph Weizenbaum
In many languages, including GreetLang+ and it's predecessor GreetLang
, you can of course write code straight away. For example, in C, you can just slap in an int main()
and get writing! However, the truth is, you actually can't. Why is this? And why am I going back on something that I just stated? Well, you can do this, but it's definitely not advised, and it'll make your program cease to run.
Let me explain.
Look at this C code:
int main(){
printf("Hello, world!\n");
return 0;
}
Ah yes, sweet, sweet familiarity. This is part of the most famous program ever, the C Hello World
program, created by Brian Kernigham
, for the C Programming Language
book in 1973. But wait, something is missing, what could it be?
Well, at the top of the program, we're missing the essential line of code that imports the standard library the language uses, containing all of the printf functions, variable and function defining methods, return types, etcetera.
#include <stdio.h>
int main(){
printf("Hello, world!\n");
return 0;
}
There, thats better!
In conclusion, you can write code, but without including the standard libraries for the code to function, the compiler has no idea what the heck you're talking about!
Now, how does all this tie back to GL Plus? Well, in GreetLang+, you would not need to include/import any libraries for the language to gain basic functionality. However, when working with arithmetics and mathematics and booleans, it just wont function without importing the libraries that contain the info for the compiler to understand that code.
Before we begin,
Here is a list of what GreetLang+ comes pre-packaged with:
op() <-- OutPut is essentially the "print" function.
func st() <-- "Function Start()" is essentially "int main()". mostly all of the code goes inside of it
while <-- While loops
for <-- For loops
if <-- If statement
elif <-- Else If statement
else <-- Esle statement
import <-- essentially "#include". used for importing libraries into the code
It knows how to create a variable:
def var [varname] = [value]
And how to create functions:
func [funcname](parameters [if none leave blank]) rt:userdef[]{
[code]
}
Preprocessing (must go directly below any library imports, also no semicolons needed):
!PPR{
#mac [macro name] = [type]
}
(or like this):
!PPR{
#mac [macro name](parameters) \
[code] \
[when going over multiple lines use backslash -> \]
}
Keep in mind that these will be explained later on.
Begin your first GL+ program by creating a .gp
file. This should create a new GreetLang+ file and allow for it to be edited.
You can use whatever editor you like, to be honest, it doesn't really matter!
Alright, lets start.
Begin by calling the start
function. You do this by typing func st()
, followed by it's return type (int)
, and two curly brackets {}
![Screenshot 2023-06-06 at 21 45 17](https://private-user-images.githubusercontent.com/104099162/243826844-2cd2ca53-3cf4-42b9-bf28-69e83e5d71b8.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk5NDYxNjUsIm5iZiI6MTczOTk0NTg2NSwicGF0aCI6Ii8xMDQwOTkxNjIvMjQzODI2ODQ0LTJjZDJjYTUzLTNjZjQtNDJiOS1iZjI4LTY5ZTgzZTVkNzFiOC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxOVQwNjE3NDVaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1lNWNlMzhmNTJjMGUyNDdmOGYzNThlNWIxYmI3OWMwMDQ1YjUxNTM5NDc1ZTY2NTNiOTY1ODUxZjY0MzZlNzQ1JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.Yvwx4nVf3CHJGYzHFR5ZFsX0sutTX5ju2f4vDdTVe8o)
Alright, let's break this down. func st()
is how we start the program, mostly all of our code will go inside of st()
, as it is a renamed version of the tried and true main()
. There's a blank space in the brackets, because all functions can
(not must
) take parameters, however, we won't get into that now. Okay, so, you might be wondering what in the world rt:int[0]
means. Well, it's a way of telling the GreetLang+ compiler that we want our function to return an integer, (either 0 or 1)
, 0 being a code
that tells us that our program has run succesfully
, and 1, obviously doing the opposite
.
Let's move on to the next part now.
![Screenshot 2023-06-06 at 21 47 13](https://private-user-images.githubusercontent.com/104099162/243827264-d414f80a-828e-40eb-bd56-06886f0091fd.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk5NDYxNjUsIm5iZiI6MTczOTk0NTg2NSwicGF0aCI6Ii8xMDQwOTkxNjIvMjQzODI3MjY0LWQ0MTRmODBhLTgyOGUtNDBlYi1iZDU2LTA2ODg2ZjAwOTFmZC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxOVQwNjE3NDVaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT00YTJhNjcxZWU5MTFlNjFhMTc3NjdjNGVkMmJjMTg4ZTAxMjJhYjZiMDk1NWU1ZWZhMmUxNDRhZGMwNmQ5NzhkJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.O-5RMTTVZkxvZcmJMEuyhXxQPMKEJy1IDIa4eO1SNL0)
Using the op()
(output) function, we can output some text to the screen. In this case, we're displaying "Hello, world!"
for everyone to see. If you're an experienced C developer, you may be wondering why we don't include an return 0;
in our code. This is because we already specify the return type in the first line of code! To remind you, here is what I'm talking about: func st() rt:int[0]
Oh, and one more thing, normally an op() function automatically creates a newline when moving on to the next line of code, like in Python
, so it's more of an ease of life feature. However, this can be turned off by adding this to the beginning of your start function
:
![Screenshot 2023-06-06 at 21 47 48](https://private-user-images.githubusercontent.com/104099162/243827551-1367ee3d-46e3-4dd1-9a56-a1ab025888a7.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk5NDYxNjUsIm5iZiI6MTczOTk0NTg2NSwicGF0aCI6Ii8xMDQwOTkxNjIvMjQzODI3NTUxLTEzNjdlZTNkLTQ2ZTMtNGRkMS05YTU2LWExYWIwMjU4ODhhNy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxOVQwNjE3NDVaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1mNTQwZDRkYzMzYjM1MjZkNmQxY2VlNzlkYTVmZWJiY2YyNzJmZGM4NWE5Yjg4OWI2ODMwYTg3ZjI5NzVkNjU3JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.gz8IZjrqdmhvXCpR4hU8fh-AXuUsw5l8MjauXb01BBI)
With this at the top of the start function
, the following code would go from outputting,
Oh, automatic newlines are disabled now...
I sure hope this doesn't do anything bad!
To
Oh, automatic newlines are disabled now...I sure hope this doesn't do anything bad!
Remember, you can manually insert a newline using "\n"
at the end/beginning of your op(), like this:
![Screenshot 2023-06-06 at 21 50 03](https://private-user-images.githubusercontent.com/104099162/243828260-ceae8596-7f8a-40dc-a55c-eea6c20ef127.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk5NDYxNjUsIm5iZiI6MTczOTk0NTg2NSwicGF0aCI6Ii8xMDQwOTkxNjIvMjQzODI4MjYwLWNlYWU4NTk2LTdmOGEtNDBkYy1hNTVjLWVlYTZjMjBlZjEyNy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxOVQwNjE3NDVaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1kOGNiYWExYmE5ZWFhMTVkNjhjMTdhMWYxY2MzNGY0ZDdkMzJiNjYzZjM5YmZkZTIxMGUwZWY1YmYxZjJlYzNjJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.b64ZmXjc-6Hfp-l8YPQcFvRZjhRKgBJm_ExPqfPiCYE)
Now that we've created our program, we need to compile and run it. Here's how we do that.
Open up your terminal, and enter in the text, gpc [filename.gp]
This is telling the GreetLang+ Compiler
(gpc)
, to compile our code. We dont need to name the binary file that is produced, as we would in C, it just auto names it to your file name.
![Screenshot 2023-06-06 at 21 53 56](https://private-user-images.githubusercontent.com/104099162/243832434-c429c000-ce5d-4e28-9ec1-11fc09284dd3.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk5NDYxNjUsIm5iZiI6MTczOTk0NTg2NSwicGF0aCI6Ii8xMDQwOTkxNjIvMjQzODMyNDM0LWM0MjljMDAwLWNlNWQtNGUyOC05ZWMxLTExZmMwOTI4NGRkMy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxOVQwNjE3NDVaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0xZTYyMTBiYjM1NTU5MDdiZWQ2MDUyOThkNmQ1YzBkMTRlY2NlYTgwMjNkOTNlYTdiNzEwMWIxMDc2MGNlNjUwJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.xKJkjfEt9DSC1oKyAfOEWOEgBGAhnLHpi0iw5hzHmqQ)
![Screenshot 2023-06-06 at 22 08 30](https://private-user-images.githubusercontent.com/104099162/243832529-757c0ea7-1f3a-4901-8fd3-6828c3224b5f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk5NDYxNjUsIm5iZiI6MTczOTk0NTg2NSwicGF0aCI6Ii8xMDQwOTkxNjIvMjQzODMyNTI5LTc1N2MwZWE3LTFmM2EtNDkwMS04ZmQzLTY4MjhjMzIyNGI1Zi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxOVQwNjE3NDVaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1kMzczMDM1YWY4ODA5NjQ1MmFkYzA2MzgzZGYzOWE2NTZlNGIyZWVlMTRhMjdhNjU2OTQwMDAwZGU2MWQxMWVhJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.aC-MysNNV3eLGX2Y_KmB6paWrpoiDxP3ZWiiaP35iJo)
After compiling, if we write ./[filename]
, we can run our code.
The output should be this:
![Screenshot 2023-06-06 at 22 11 52](https://private-user-images.githubusercontent.com/104099162/243833937-91bd6ab9-e456-4ff5-8c5d-9f046b54941b.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk5NDYxNjUsIm5iZiI6MTczOTk0NTg2NSwicGF0aCI6Ii8xMDQwOTkxNjIvMjQzODMzOTM3LTkxYmQ2YWI5LWU0NTYtNGZmNS04YzVkLTlmMDQ2YjU0OTQxYi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxOVQwNjE3NDVaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1mMGE3NjFjNDExNjM5ZDYwZmVkOGU1ODY3NzcyYzNiZWUwNWVmZDFjMzVkNGI2MTRhYTZhNGM1NDFiM2M2NjA1JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.ggUnBzIV57ZRpjdufQbnTkzyzF8KKex4E9Dsht2UIpA)
![Screenshot 2023-06-06 at 22 14 21](https://private-user-images.githubusercontent.com/104099162/243833988-0e5a4de0-6a32-45a9-91d3-6d6d1e5cbe14.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk5NDYxNjUsIm5iZiI6MTczOTk0NTg2NSwicGF0aCI6Ii8xMDQwOTkxNjIvMjQzODMzOTg4LTBlNWE0ZGUwLTZhMzItNDVhOS05MWQzLTZkNmQxZTVjYmUxNC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxOVQwNjE3NDVaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0xZDkwMTMwMWU1ZWIxMmZkZWMxNThjNGUwZDBhM2Y3ODVlYjhjOWQyMzFkMzE5YTFkYTRiMDk5MjcwMTFkYjBiJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.V9j2P6tbE2MBNit4u4wYXHNi_j9RzNGge8LX4_aEqHg)
Great job! You've just written your first GreetLang+ code! You're now ready to become a professional GL+ developer! :D
Talk is cheap. Show me the code.
- Linus Torvalds
Ah yes, variables
, the go-too way of storing data in a sort of container.
Think of a variable as a box, which you can name and can put things inside. The items you would put inside
the box are the values you assign
to the variable. For example in C, if you wanted to give a variable a value of an integer
, you would do something like this:
int num1 = 87;
That is an example of putting a value in our box
. In this case, the value is the integer
87, and now that the variable has been created and assigned a value, we can use it later in our code.
GreetLang+ is a bit different. You start by using the def
keyword. This stops any confusion you would have in C like int
and char
and char varname[100]
(<-- Character array
, I'll go in to how that's different in GreetLang+ soon), so it's just define
. Nothing confusing.
Following that is var
, which tells the GL+ compiler that we're defining a VARIABLE
, not something else. Next up is the variable name, and it's value. Make sure to end the line of code with a semicolon!
![Screenshot 2023-06-06 at 22 24 19](https://private-user-images.githubusercontent.com/104099162/243836067-d54a272b-ea67-4bd5-9e88-f781c05d0f09.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk5NDYxNjUsIm5iZiI6MTczOTk0NTg2NSwicGF0aCI6Ii8xMDQwOTkxNjIvMjQzODM2MDY3LWQ1NGEyNzJiLWVhNjctNGJkNS05ZTg4LWY3ODFjMDVkMGYwOS5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxOVQwNjE3NDVaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT04OWEwYWY3MWZlYWYwY2IwYTJkNjNhN2UwOWZhMWIxODM1MGQxMzk5YmVmOTMxZDIzMjA5NzgyZDBhZThmOWY5JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.0ob9p0gMjwkcbOBct1-ZwkoC10T8gG1bScIRU81O5HQ)
I said I was going to go into how character arrays are different in GL+, so I'll quickly skim over that and move on.
In C and many other older languages, they didn't necessarily have string types
, so their alternative was to create an array of characters
and use that instead. Obviously this is just a more complicated way of writing strings
, as they are obviously character arrays if you think about it.
An array is a spreadsheet of information,
a character is a single letter,
and a character array is a collection of characters that can form a sentence or a name or whatever you want.
Starting to see my point here?
Now let's move on to how you would actually use one in your code.
Below is the code to include a variable with an integer
value in an output (op)
:
![Screenshot 2023-06-06 at 22 26 00](https://private-user-images.githubusercontent.com/104099162/243836497-45c02d76-dd3f-40f3-a64b-b691356d1c0e.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk5NDYxNjUsIm5iZiI6MTczOTk0NTg2NSwicGF0aCI6Ii8xMDQwOTkxNjIvMjQzODM2NDk3LTQ1YzAyZDc2LWRkM2YtNDBmMy1hNjRiLWI2OTEzNTZkMWMwZS5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjE5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxOVQwNjE3NDVaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT02ODNlNDMxMDY0NGY0OWMyYTE5ZTA5OWMwNDVhOGUwM2ZjMWE5MjkyNzkyNjFkZDAxYjVkOThjNzQ2OWU2NDg3JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.Hfl78A_4ENNS5wmrT_1Y5g3afXluM-du5rIBHEuQMVY)
Surrounding a variable name in curly brackets and an exclamation mark tells the GL+ compiler that we want to put a variable in that position. When doing this, you won't have to worry about converting the number to a string, or any nonsense like that, the lovely GL+ compiler automatically does it for you. Thanks GL+ compiler!
Click on More Examples
for some extra examples of variables in GreetLang+
More Examples
func st() rt:int[0]{
def var greeting = "Hey there!";
op("{!hello}"); // outputs "Hey there!" to the terminal
}
Hi!
func st() rt:int[0]{
def var middle_name = "Jackson"
def var surname = "Kerg";
op("Hello, my name is Samuel {!middle_name} {!surname}. What's yours?");
}
Hello, my name is Samuel Jackson Kerg. What's yours?
Before we go into any more detail about variables in GreetLang+, let's go over some basic variable naming rules.
You can use any characters in the range 0-9, A-Z, a-z, and underscore for variable names, with the following rules:
• You can’t start a variable with a digit 0-9.
• You can’t start a variable name with two underscores.
Now that we have that cleared up, let's continue!
You can add integer variables quite easily, by containing the equation you would like to calculate in a single {!}
. This is a feature in GL+ that reduces the complication of, for example, in C, where you would have to do a complicated mess of remembering the calling characters for specific variable types.
int main() {
int num1 = 22;
int num2 = 23;
printf("%d", num1 + num2);
}
The C code can be shortened very much in GL+, as you can see in this code below that shows how to add integer variables in it.
func st() rt:int[0]{
def var num1 = 22;
def var num2 = 23;
op("{!num1 + num2}");
}
The GreetLang+ compiler, as stated before, automatically checks what type a variable is, so you wont have to worry about
"%d" or "%f" or "%lf"
One neat feature most programming languages, including GL+ have is giving variables the value of the answer to an equation. Yeah, that probably sounds vague as hell, so let me quickly explain it.
func st() rt:int[0]{
def var RandomNumberWithAnExtremelyLongVariableName = 2 * 2;
op("{!RandomNumberWithAnExtremelyLongVariableName}");
}
This code is actually a perfect example for GreetLang-Plus's Short-hand Variable Names
, but thats for later. In the code above, we make RandomNumberWithAnExtremelyLongVariableName
equivalent to 2 times 2
(which as we all know is 4), this is just a neat little thing we can do. There is also something else you can do, using mathematical operators. This is the first time we'll have to import a library into GreetLang+
We can do this via the import
keyword. This is just what we use in Python to import libraries. It's the exact same as #include
in C.
Note that you do not need to end imports
with a semicolon.
import math.gph // greetlang plus header file
func st() rt:int[0]{
def var number1 = sqr("22"); // squares the number
op("{!number1}"); // outputs "484"
}
We won't have to go over much in this section, as it's essentially the same process as adding integer vairables together, just with an extra step.
We'll start by defining our variables
and st()
function.
func st() rt:int[0]{
def var part1 = "Foot";
def var world = "ball";
}
Great!
The next step would be to combine the strings, by using a function called strmerge()
. What string-merge
does is it combines two strings together. It is used inside of the {!}
.
func st() rt:int[0]{
def var part1 = "Foot";
def var part2 = "ball";
op("{!strmerge(part1, part2)}");
}
Now we can compiler our program and run it. The result will be,
Football
Pretty neat, right?
Note, you can create a new variable equivalent to the two variables merged together and output that, it's optional and doesnt affect the code.
E.g:
func st() rt:int[0]{
def var str1 = "he";
def var str2 = "llo";
def var hello = strmerge("he, llo");
op("{!hello}")
}
Output:
hello
We're finally nearing the end of the varibles section, and boy has it been long! Speaking of long
, have you ever felt that your variables are just WAY too lengthy, but if you abbreviate them, they just become confusing? Yeah, me too. Well, in GreetLang+, there's a cool feature which lets you nickname your variables. So, let's get into explaining it, shall we?
(For now, I'll refer to
Short-hand Variable Names
asNicknames
)
Sure, you could just shorten down your variable names. However, that would make code less readable to the person reading it. For example, look at this code, do you know what the variable is?
#include <stdio.h>
int main(){
int RLV1 = 72;
int ORLV1 = 22;
printf("%d", RLV1 * ORLV1);
return 0;
}
I would say probably not. But if you swapped out the variable abbreviation for it's actual full name, it's now too long!
#include <stdio.h>
int main(){
int ReallyLongVariable1 = 72;
int OtherReallyLongVariable1 = 22;
printf("%d", ReallyLongVariable1 * OtherReallyLongVariable1);
return 0;
}
The solution is to have a line of code that specifies that the abbreviation is that variable, which makes the code more readable.
Back to GreetLang+, here are our excessively long variables:
func st() rt:int[0]{
def var OneThousandTimesTwo = 1000 * 2;
op("One thousand times two is {!OneThousandTimesTwo}");
}
We can shorten this down using a nickname.
func st() rt:int[0]{
def var OneThousandTimesTwo:<OneKx2> = 1000 * 2;
op("One thousand times two is {n:OneKx2}");
}
In this case we give OneThousandTimesTwo
a nickame of OneKx2
. For the rest of the code, when we use OneKx2
, we'll know that we're referring to OneThousandTimesTwo
!
Also, when you give a variable a nickname, it is still alright to use the original name, but it might get confusing if you keep switching between using a variable's nickname and it's real name. When using a nickname, to output it, instead of an exclamation mark, you would use n
followed by a colon :
, to let the compiler know it's a nickname. Not doing this will result in an error.
Nicknames are optional!
Well, that took quite a long time! We can finally move on!
I wonder what's next?
You Can't Write Perfect Software. Did that hurt? It shouldn't. Accept it as an axiom of life. Embrace it. Celebrate it. Because perfect software doesn't exist.
- Andrew Hunt, The Pragmatic Programmer: From Journeyman to Master
So, by now, you're probably wondering how we can get user input in GreetLang+
Many langages have that as a feature, so of course this one does. But how do we make it simple
?
C has a complicated mess of fgets
and scanf
and not accepting newline characters
even though they are required, and it's all one massive jumble of unpractical, hard to read- yeah, you get the point.
Javascript
uses prompt()
, which is understandable, more tied to web-development. Go
uses a similar thing to C
, with scan
, however, it does use fmt.Scan()
, which just looks nice to me, so we'll take a page out of that.
Now we have:
def var name = [placeholder].op("What is your name?");
// or on it's own: [placeholder].op();
Nice! Let's move on.
R
uses readline
, which I like so I'll keep that in mind. What's next? Oh no...
Java is just this cryptic mess. Yeah, I'm showing you the whole thing because I literally don't even know where the input
is taken.
import java.util.Scanner; // import the Scanner class
class Main {
public static void main(String[] args) {
Scanner myObj = new Scanner(System.in);
String userName;
// Enter username and press Enter
System.out.println("Enter username");
userName = myObj.nextLine();
System.out.println("Username is: " + userName);
}
}
Moving swift
-ly on (get it?), Ardui
- oh. That's essentially the same as R
. MatLab
? Too basic. And literally the exact same as Python
. I could of course make my own way of getting user input, this is my language after all. Let me think...
def var name = getinp.op("What's your name?");
// or on it's own, getinp.op();
Or,
def var name = readline.op("What's your name?");
// or on it's own, readline.op();
After 5 long minutes of pondering, readline
it is!
We now have a way of asking for user input. Let's try it out!
import gpultim.gph
func st() rt:int[0]{
def var tries = 0;
op("Booting...");
while tries < 6 {
def var user = readline.op("Hello, welcome to PIE OS. What is your username? ");
// if username is correct
if user == "pr0gramme5" {
def var pass = readline.op("Please enter your password to continue. ");
// if password is correct
if pass = "sharksurfer23"{
op("Welcome, {!user}");
end; // ends while loop
}
// if password is incorrect
else {
op("Incorrect, try again.");
tries += 1;
}
}
// if username is wrong
else {
op("Incorrect, try again.");
tries += 1;
}
}
More cryptic than I expected, but hey at least that's a finished product! (Oh God I've got to rethink the whole language now don't I...)
._.
“One of my most productive days was throwing away 1000 lines of code.”
- Ken Thompson
Functions are at the core of every programming language. In fact, what we write our code inside of, IS a function! (start function)
They are used to save time, resources, do repetitive tasks, store data more easily, etcetera.
Greet, or GreetLang
, GreetLang+'s predecessor, had a very simmilar but less intuitive way of defining functions, which often resulted in hard to read code. GreetLang+ was only created because Greet
quickly became a jumbled mess of horrible structure, ideas, lack of readability, and more. It's pretty obvious that I would try and improve functions in it's successor.
As you may know, functions can be defined using the func
keyword, followed by the function's name. Directly next to that, inside brackets would be the function's parameters
. Parameters can be used to to refer to one of the pieces of data provided as input to the function. Say for example, we wanted to add two numbers together, we could give the function parameters of num1
and num2
, and later on in it's code, specify we want the numbers that we give it to be added together.
After the parameters, we need to specify the return type (which is required). Because the function has a user defined return type, we just need to specify that by saying: rt:userdef[]
. If your function does not have a return type, for example, it outputs
something instead, you would change it to rt:userdef[void]
.
Let's use this knowledge to create a function that times two numbers together.
Start by defining the name
, parameters
, and return type
.
func times(num1, num2) rt:userdef[]{
// our code goes inside here!
}
We're off to a good start!
Now, let's times num1
and num2
together, by creating a variable called prod
(product)
and returning that.
func times(num1, num2) rt:userdef[]{
def var prod = num1 * num2;
return prod;
}
Note, you can also just make the function return
num1 * num2
without specifyingprod
.
Great job!
Now, inside our st()
function, we can use times()
and give it two numbers two times.
func st() rt:int[0]{
times(4, 6);
}
Alright! Let's see the output!
Nothing.
Why? Well, when you return
something in a function, it doesnt automatically output. You need to include it INSIDE
an op()
to get a result. Let's quickly change that, shall we?
func st() rt:int[0]{
op(times(4, 6));
}
Alright, let's compile and run!
24
Hooray! It was a success!
Again, the issue with having to include the function in an op()
could also be solved by altering the code to this:
func times(num1, num2) rt:userdef[void]{
def var prod = num1 * num2;
op("{!prod}");
}
func st() rt:int[0]{
times(4, 6);
}
The void
is what tells the compiler we aren't necessarily returning
anything, instead opting to output.
Another neat thing we can do is set a variable equivalent to the output of a function, as seen in §6.3 with strmerge()
, where it is stated that you can set a new variable equivalent to the result of two or more variables merged together:
func st() rt:int[0]{
def var part1 = "ok";
def var part2 = "ay";
def var fullword = strmerge(part1, part2);
op(fullword);
}
You can also do this with other types of variables. For example, if you created a function that cubes a number (without using the math.gph
library), and then a variable equal to that number cubed, you could use it for other things.
func cube(num1) rt:userdef[]{
return num1 * num1 * num1;
}
func st() rt:int[0]{
def var exponent = cubed(16);
op("{!exponent}")
}
Why don't we take a quick stop and compare declaring functions in GreetLang to GreetLang+?
If you do not really care about the details of how much the Greet
language family has changed, please do not refrain from skipping forward!
Why not create an add numbers
for this example.
// GreetLang Original:
func add_nums(num1: int, num2: int) rt integer {
let sum: int = num1 + num2;
return sum;
}
As you can see, this is very similar to GreetLang+ (which will become apparent when I recreate this function in it), and oddly, Carbon
. The main difference is the big rt integer
which is used to, of course, specify the function returns an integer. The thing is, if not outputting any specific data type, you can't really do much. There is no void
like in C to specify this. That's why in GreetLang+, you dont even need to specify the specific return type anymore, just that it will be user decided, with rt:userdef[]
.
// GreetLang+
func add_nums(num1, num2) rt:userdef[]{ // user defined return type (in this case, sum)
def var sum = num1 + num2;
return sum;
}
GreetLang+ has a slight improvement, with less needed to be specified, a smaller emphasis on colons (:)
, and also a user defined return type
. Less boilerplate equals better workflow!
Do you ever find yourself drowning in a sea of long and tedious function definitions? Well, fear not, my friend, for I have the perfect comedic solution for you: Autofunc, the hero of lazy programmers everywhere!
Picture this: you're tired, you're cranky, and you just can't bear the thought of writing another lengthy function. Enter Autofunc, the magical tool that lets you conjure up small, inline functions without the hassle of creating separate named monstrosities.
But wait, there's more! With Autofunc, you can say goodbye to those never-ending lines of code. No more fussing over complex function structures that span the length of a football field. Yeah, short and sweet is the way to go- sorry Java developers...
Let's take a gander at this marvelous creation, shall we?
// Defining an autofunc for `add`
autofunc add -> x, y: x + y;
Behold, the mighty autofunc add
! With just a few cryptic symbols, you can summon the power of addition itself 😳.
Let's break down this enigma. Brace yourselves for the formula that will revolutionize the way you write smaller functions:
autofunc [name] -> [parameters]: [expressions];
See? It's so easy! It may seem cryptic at first, but once you crack the Autofunc code
(Patent pending), you'll be more effecient than ever.
So, why waste precious time and energy on lengthy function definitions when you can embrace the genuis of autofunc?
There sadly is one downside to autofuncs though. Since their return type isn't defined by the creator, all autofuncs must be contained inside of an op()
function 😭.
The code above would be ran like this:
// Add autofunc
autofunc add -> x, y: x + y;
// Start func
func st() rt:int[0]{
op(add(2, 2)); // 4
}
When compared to the normal way of writing add
, this really is a lot more efficient!
// Add func
func add(x, y) rt:userdef[]{
return x + y;
}
// Start func
func st() rt:int[0]{
op(add(2, 2));
}
“Programming goes like this: You've baked a really lovely cake, but then you've used dog crap for frosting.”
― Daniel editing one of Steve Jobs' qoutes.
What would a programming language be without Classes? Ah, OOP, sweet, sweet Object Oriented Programming.
To be as functional as possible, GreetLang+ does in fact include Classes. After breaking their heart, now I can undo my bad deeds. Java developers, welcome, because you're definitely going to love this!
You can easily define a class using the class
keyword, obviously.
class MyClass{
// code goes here
}
See how convenient that is? Really makes you want to forget any other language and adopt GreetLang+
, right?
LANGUAGE REVOLUTION!
But let's get back to the code. It's a common convention to capitalise the first letter of every new word in the name of a class. As shown in the example above, MyClass
follows this. To be honest, it's like the opposite of naming functions! Never thought about that, actually.
But what even is the point of classes? Well, to put it simply, a class is a way of organizing information about a type of data so we can easily reuse elements when making multiple instances of that data type— for example, if a programmer wanted to make three instances of Car
(in this case Car
is the class), maybe a BMW
, a Ferrari
, and a Ford
instance. The Car
class would allow us to store similar information that is unique to each car (they are different models, and maybe different colors, etc.) and associate the appropriate information with each car.
Let's demonstrate this with code.
class Car{
// code goes here
}
Now that we've created our Car
class, we can define some basic functions, variables, etcetera.
class Car{
// generic car stuff
def var max_speed = 220;
def var wheels = 4;
// all cars gotta vroom vroom
func vroom() rt:userdef[void]{ // the void in rt:userdef[void] lets us output instead of return
op("Vroom vroom!");
}
}
The variables we define are: max_speed
and wheels
. We also create a function called vroom()
which outputs "Vroom vroom!" to the screen.
So if we wanted to use this, we would create a new variable and give it the properties of car. Let's call it car
, since that's the simplest option.
def var car = Car;
Now we can just write car.[something]
You could change the values of objects (the variables, functions, etcetera) inside the class, like this:
car.max_speed = 250;
The value of max_speed is now 250, instead of 220.
Here's another easy example:
class Vehicle{
func drive() rt:userdef[void]{
op("The vehicle is driving");
}
func stop() rt:userdef[void]{
op("The vehicle has stopped");
}
}
We've defined a Vehicle
class, and two functions, drive()
and stop()
. We can use those functions by setting a variable equal to Vehicle
.
class Vehicle{
func drive() rt:userdef[void]{
op("The vehicle is driving");
}
func stop() rt:userdef[void]{
op("The vehicle has stopped");
}
}
def var vehicle_1 = Vehicle;
Now we can write vehicle_1.drive()
to use drive!
Here's where things get fun. Inheritance, what does it mean?
Well, now that we have Car
defined, we can create new classes and even variables that inherit
the features of it's Parent
, in this case, Car, like we did earlier. Let's create a new Car-type class. We can do this using the extends
keyword. It lets the compiler know it is a Child
of Car.
class Ford extends Car{
// code goes here
}
Nice job! You can just use the stuff inside of car like this:
def var ford = Ford;
ford.vroom();
But if we put nothing in the class, we get an error, so if you ever want to use nothing inside of a Class or Function, just use the pass
keyword.
class Ford extends Car{
pass;
}
That's better!
With the basic stuff outta' the way, let's move onto some more complex stuff.
Why not give the Ford
some new features?
class Ford extends Car{
ovveride var max_speed = 300;
}
We use ovveride
to change the variable max_speed
only for Forda. If you did op(car.max_speed)
you would still get 220
.
If we just did var max_speed = 300;
we would change the value of max_speed for every class, which isn't what we're going for!
You can ovveride functions to change their contents as well.
Click on More Examples
for some extra examples of ovveriding in GreetLang+
More Examples
class Train extends Vehicle{
override func makeNoise(){
op("Choo choo!");
}
}
let train = Train;
train.makeNoise();
// Prints "Choo choo!"
You can also set a new variable equal to one in a different class.
class Snake extends Reptile{
def var favourite_foods2 = favourite_foods;
}
And if you had a class which contained a function that added two numbers together, you could set a variable with a value equivalent to the output of it:
class MathOperators{
// adds two numbers and returns (not outputs)
func add(num1, num2) rt:userdef[]{
return num1 + num2;
}
}
math = MathOperators;
conditional_1 = math.add(89, 60);
op("{!conditional_1}");
// Prints "149"
Or like this:
class MathOperators{
// adds two numbers and returns (not outputs) the result
func add(num1, num2) rt:userdef[]{
return num1 + num2;
}
}
conditional_1 = MathOperators;
conditional_1.add(89, 60);
op("{!conditional_1}");
// Prints "149"