Continue with the Basics by Example; today's version of the post written in Nemerle Enjoy!
You can copy and paste the code below in your favorite IDE/Editor and start playing and learning with it. This little "working" program will teach you the basics of the Programming Language.
There are some "comments" on the code added just to tell you what are or how are some features called. In case you want to review the theory, you can read my previous post, where I give a definition of each of the concepts mentioned on the code. You can find it here: http://carlosqt.blogspot.com/2010/08/new-series-languages-basics-by-example.html
Greetings Program - Verbose
// Nemerle Basics using System; namespace NGreetProgram { // Greeting Class internal class Greet { // Fields or Attributes private mutable message : string; private mutable name : string; private mutable loopMessage : int; // Properties public Message : string { get { this.message; } set { this.message = this.Capitalize(value); } } public Name : string { get { this.name; } set { this.name = this.Capitalize(value); } } public LoopMessage : int { get { this.loopMessage; } set { this.loopMessage = value; } } // Constructor public this() { this.message = ""; this.name = ""; this.loopMessage = 0; } // Overloaded Constructor public this(message : string, name : string, loopMessage : int) { this.message = message; this.name = name; this.loopMessage = loopMessage; } // Method 1 private Capitalize(val : string): string { if (val.Length >= 1) { val[0].ToString().ToUpper() + val.Substring(1, val.Length - 1); } else { ""; } } // Method 2 public Salute() : void { // "for" statement for (mutable i : int = 0; i < this.loopMessage; i++) { Console.WriteLine("{0} {1}!", this.message, this.name); } } // Overloaded Method 2.1 public Salute(message : string, name : string, loopMessage : int) : void { // "while" statement mutable i : int = 0; while(i < loopMessage) { Console.WriteLine("{0} {1}!", this.Capitalize(message), this.Capitalize(name)); i++; } } // Overloaded Method 2.2 public Salute(name : string) : void { // "switch/case" statement is not supported // using match statement instead def dtNow : DateTime = DateTime.Now; match (dtNow.Hour) { |6|7|8|9|10|11 => this.message = "good morning,"; |12|13|14|15|16|17 => this.message = "good afternoon,"; |18|19|20|21|22 => this.message = "good evening,"; |23|0|1|2|3|4|5 => this.message = "good night,"; | _ => this.message = "huh?" } Console.WriteLine("{0} {1}!", this.Capitalize(this.message), this.Capitalize(name)); } } // Console Program public module Program { public static Main() : void { // Define object of type Greet mutable g : Greet; // Instantiate Greet. Call Constructor g = Greet(); // Call Set Properties g.Message = "hello"; g.Name = "world"; g.LoopMessage = 5; // Call Method 2 g.Salute(); // Call Overloaded Method 2.1 and Get Properties g.Salute(g.Message, "nemerle", g.LoopMessage); // Call Overloaded Method 2.2 g.Salute("carlos"); // Stop and Exit Console.WriteLine("Press any key to exit..."); _ = Console.Read(); } } }
Greetings Program - Minimal
// Nemerle Basics using System; // Greeting Class class Greet { // Fields or Attributes mutable message : string; mutable name : string; mutable loopMessage : int; // Properties public Message : string { get { message; } set { message = Capitalize(value); } } public Name : string { get { name; } set { name = Capitalize(value); } } public LoopMessage : int { get { loopMessage; } set { loopMessage = value; } } // Constructor public this() { message = ""; name = ""; loopMessage = 0; } // Overloaded Constructor public this(message : string, name : string, loopMessage : int) { this.message = message; this.name = name; this.loopMessage = loopMessage; } // Method 1 private Capitalize(val : string): string { if (val.Length >= 1) { val[0].ToString().ToUpper() + val.Substring(1, val.Length - 1); } else { ""; } } // Method 2 public Salute() : void { // "for" statement for (mutable i = 0; i < loopMessage; i++) { Console.WriteLine("{0} {1}!", message, name); } } // Overloaded Method 2.1 public Salute(message : string, name : string, loopMessage : int) : void { // "while" statement mutable i = 0; while(i < loopMessage) { Console.WriteLine("{0} {1}!", Capitalize(message), Capitalize(name)); i++; } } // Overloaded Method 2.2 public Salute(name : string) : void { // "switch/case" statement is not supported // using match statement instead def dtNow = DateTime.Now; match (dtNow.Hour) { |6|7|8|9|10|11 => message = "good morning,"; |12|13|14|15|16|17 => message = "good afternoon,"; |18|19|20|21|22 => message = "good evening,"; |23|0|1|2|3|4|5 => message = "good night,"; | _ => message = "huh?" } Console.WriteLine("{0} {1}!", Capitalize(message), Capitalize(name)); } } // Console Program // Define object and Instantiate Greet. Call Constructor def g = Greet(); // Call Set Properties g.Message = "hello"; g.Name = "world"; g.LoopMessage = 5; // Call Method 2 g.Salute(); // Call Overloaded Method 2.1 and Get Properties g.Salute(g.Message, "nemerle", g.LoopMessage); // Call Overloaded Method 2.2 g.Salute("carlos"); // Stop and Exit Console.WriteLine("Press any key to exit..."); _ = Console.Read();
And the Output is:
Nemerle in Indentation Mode
Nemerle provides a very cool feature that allows you write your code in C-Like code blocks { } or Python-like indentation. You can do that using a compiler switch, or by adding a #pragma instruction to your code. Let's look at the Greetings Program (Minimal) and how it looks like after removing all those { and } characters from it, or should I say "Let's see how Pythonic it looks like?" hehe...
#pragma indent using System; class Greet mutable message : string; mutable name : string; mutable loopMessage : int; public Message : string get message; set message = Capitalize(value); public Name : string get name; set name = Capitalize(value); public LoopMessage : int get loopMessage; set loopMessage = value; public this() message = ""; name = ""; loopMessage = 0 public this(message : string, name : string, loopMessage : int) this.message = message; this.name = name; this.loopMessage = loopMessage; private Capitalize(val : string): string if (val.Length >= 1) val[0].ToString().ToUpper() + val.Substring(1, val.Length - 1); else ""; public Salute() : void for (mutable i = 0; i < loopMessage; i++) Console.WriteLine("{0} {1}!", message, name); public Salute(message : string, name : string, loopMessage : int) : void mutable i = 0; while(i < loopMessage) Console.WriteLine("{0} {1}!", Capitalize(message), Capitalize(name)); i++; public Salute(name : string) : void def dtNow = DateTime.Now; match (dtNow.Hour) |6|7|8|9|10|11 => message = "good morning,"; |12|13|14|15|16|17 => message = "good afternoon,"; |18|19|20|21|22 => message = "good evening,"; |23|0|1|2|3|4|5 => message = "good night,"; | _ => message = "huh?" Console.WriteLine("{0} {1}!", Capitalize(message), Capitalize(name)); mutable g = Greet() g.Message = "hello"; g.Name = "world"; g.LoopMessage = 5; g.Salute() g.Salute(g.Message, "nemerle", g.LoopMessage); g.Salute("carlos"); // Stop and Exit Console.WriteLine("Press any key to exit..."); _ = Console.Read();
Wow, this last example looked too hybrid to me!
(C#-JScript-Boo-Python-F#) = Nemerle!
Auto-Implemented Properties in Nemerle
As with other .NET languages (C#,VB.NET,C++) Nemerle provides built in syntax to create auto-implemented properties. Auto-implemented properties enable you to quickly specify a property of a class without having to write code to Get and Set the property. The compiler will automatically create a private field to store the property variable in addition to creating the associated get and set procedures.
#pragma indent using System; /* In our class, we can void typing the Fields/Attributes and go directly to the properties */ class Greet //mutable message : string; //mutable name : string; //mutable loopMessage : int; // using pragma indent public Message : string get; set; public Name : string get; set; public LoopMessage : int get; set; // or not public Message : string {get; set;} public Name : string {get; set;} public LoopMessage : int {get; set;} // then, whenever you want to use them you access them via the Properties. // Let's see the example in our constructor public this() Message = "hola"; Name = "mundo"; LoopMessage = 0;