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;
Nice! Didn't know Nemerle had a braceless syntax option!
ReplyDeleteNemerle is really good ^_^
ReplyDeleteBut the goal is macros.
There are some really cool tutorials from main Nemerle RSDN team (But on Russian) IF you are interestied in translation I can do it just for you :)
@nCdy
ReplyDeleteThat's exactly what I was reading about Nemerle, the Macros stuff looks very interesting and lots of examples are on the courses and tutorials out there, but I will let that for future posts; probably in a new series called... "Nemerle - Language's Strengths"? :)
Thanks for the translation offer! :D
look here http://rsdn.ru/summary/3766.xml
ReplyDeleteand use Google Panel and site translator there
# mutable i = 0;
ReplyDelete# while(i < loopMessage) {
# Console.WriteLine("{0} {1}!", Capitalize(message),
# Capitalize(name));
# i++;
# }
This code can be rewritten (with standard macros) to:
#using System.Console;
#...
# repeat(loopMessage)
# WriteLine("$(Capitalize(message)) $(Capitalize(name))!");
You not need add type annotation to variables:
def dtNow = DateTime.Now;
And you can use macro-attribute [Recort] instead write ctor.
I.e. instead:
# public this(message : string, name : string, loopMessage : int)
# this.message = message;
# this.name = name;
# this.loopMessage = loopMessage;
you can simply write:
[Record] class Greet
You accessors don't do any productive work. It can be replaced by Accessor macro:
# [Accessor(flags = WantSetter)] mutable message : string;
# [Accessor(flags = WantSetter)] mutable name : string;
# [Accessor(flags = WantSetter)] mutable loopMessage : int;
or by autoproperty:
public Message : string { get; set; }
...
@nCdy
ReplyDeleteThanks nCdy, I just did it (http://rsdn.ru to english) and found the tutorials you were talking about. I will certainly have a look.
@VladD2
Thanks for your comments and suggestions Vlad. Those definitively deserve an update to the post! I will update it during the week.