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.