CSC/ECE 517 Spring 2013/ch1b 1i lh: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
 
(111 intermediate revisions by the same user not shown)
Line 1: Line 1:
*Here is a [https://docs.google.com/a/ncsu.edu/document/d/1aER6f9EDFJaUMgSpK7g5nYPiMNoUjZzwQxzY0jMW8mI/edit link] to the writing assignment for this topic.
*[https://docs.google.com/a/ncsu.edu/document/d/1aER6f9EDFJaUMgSpK7g5nYPiMNoUjZzwQxzY0jMW8mI/edit Write-up of This Topic.]
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2010/ch2_S24_rm Expertiza Wiki Entry on Meta-programming in Statically Typed Languages 1]
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2010/ch2_S24_NS Expertiza Wiki Entry on Meta-programming in Statically Typed Languages 2]
*[http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2010/ch2_S24_sk Expertiza Wiki Entry on What is Meta-programming]


''Meta-programming in Dynamically Typed Languages''
 
This page discuss implementation and uses of meta-programming in dynamically typed languages
''"I rather write a x86 program in binary [http://xkcd.com/378 using a butterfly] than writing this article" - Hao Liu''
 
This page is a discuss about meta-programming and its implementation and uses in dynamically typed languages.


__TOC__
__TOC__
= Meta-programming in Dynamically Typed Languages =


= Meta-programming =
== Introduction to Meta-Programming ==
In essence meta-programs are computer programs that can write or manipulate other programs or themselves as their data. Meta-programming is the general term for techniques use to write such program. The language in which the meta-program is written is called the [http://en.wikipedia.org/wiki/Metalanguage metalanguage]. The language of the programs that are manipulated is called the [http://en.wikipedia.org/wiki/Object_language object language].<ref>[http://en.wikipedia.org/wiki/Metaprogramming  Wikipedia Entry on Metaprogramming]</ref>


Meta-programming is a programming technique of writing computer programs that write or manipulate other programs or themselves, as their data. [http://en.wikipedia.org/wiki/Metaprogramming] This technique allow us to write program that modify its own behavior at run-time (as opposes to recompiling the program.)


This simplistic definition of meta-program and meta-programming tend to give reader a very intimidating first impression and render a image of a sentient self modifying program that ultimately take over the world. In reality meta-program and meta-programming techniques can very in complexity from the extreme of sentient self modifying program to simple and everyday thing such as a pre-processor macro. In most cases meta-programming are use to improve the quality of life of the programmer by improving the readability and re-usability of the code and by providing a higher level of abstraction.


In meta-program, the language in which the meta-program is written is called the metalanguage. The language of the programs that are manipulated is called the object language.[http://en.wikipedia.org/wiki/Metaprogramming]
== Example of Meta-Programming ==
This section describe some of diffident types of meta-programming techniques and example of their usage.


=== Generative Programming ===
Generative programming is a style of computer programming that uses automated source code creation through generic frames, classes, prototypes, templates, aspects, and code generators to improve programmer productivity.<ref>[http://en.wikipedia.org/wiki/Automatic_programming Wikipedia Entry on Automatic Programming]</ref>


The ability of a programming language to be its own metalanguage is called reflection or reflexivity.[http://en.wikipedia.org/wiki/Metaprogramming]
In its simplest form any programming language, even the [http://en.wikipedia.org/wiki/Shell_script shell script], can be use for this type of meta-programming, so long as they have the ability to reading and modifying the source code of another program or it's own source code as a text file.


== Application of Meta-programing ==
For example:
#!/usr/bin/env bash
echo -e "#include <stdio.h>" >> program.c
echo -e "int main() {"      >> program.c
for ((I=1; I<=5; I++)) do
    echo -e "  printf(\042 meta \042);" >> program.c
done
echo -e "return 0}" >> program.c
g++ program.c
a.out


First, you can write programs that will pre-generate tables of data for use at runtime. For example, if you are writing a game and want a quick lookup table for the sine of all 8-bit integers, you can either calculate each sine yourself and hand-code it, have your program build the table at startup at runtime, or write a program to build the custom code for the table before compile-time. While it may make sense to build the table at runtime for such a small set of numbers, other such tasks may cause program startup to be prohibitively slow. In such cases, writing a program to build static data tables is usually your best answer.
This simple [http://en.wikipedia.org/wiki/Bash_(Unix_shell) bash script] generates a program that prints out
meta meta meta meta meta
by generating a c source code as a text file, than compile to source code into a executable binary file using a compiler.


= Dynamically Typed Programming Languages =
=== Template Meta-Programming ===
Template meta-programming is a meta-programming technique in which templates are used by a compiler to generate temporary source code, which is merged by the compiler with the rest of the source code and then compiled. The output of these templates include compile-time constants, data structures, and complete functions. The use of templates can be thought of as compile-time execution.<ref>[http://en.wikipedia.org/wiki/Template_metaprogramming Wikipedia Entry on Template Metaprogramming]</ref>


Programming languages can be split into two categories base on their type system, dynamically and statically typed. A programming language is said to use static typing when type checking is performed during compile-time. In comparison, dynamically typed languages deferring type checking until run-time as opposes to compile-time. [http://en.wikipedia.org/wiki/Type_system]  
A example usage of template programming is to pre-generate tables of data at compile time for use at runtime. For example, if you are writing a game that require lots of calculation of sine of 8 bit integers, instead of calculating sine at run time when they are needed, template programming can be use to build a static data tables as pre-calculated value at compile-time to eliminate the need of recalculating sine each time.<ref>[http://www.ibm.com/developerworks/library/l-metaprog1/index.htmlThe art of metaprogramming, Part 1: Introduction to metaprogramming]</ref>


=== Macros ===
A macro is a rule or pattern that specifies how a certain input sequence (often a sequence of characters) should be mapped to a replacement input sequence (also often a sequence of characters) according to a defined procedure. The mapping process that instantiates (transforms) a macro use into a specific sequence is known as macro expansion. Macros are used to make a sequence of computing instructions available to the programmer as a single program statement, making the programming task less tedious and less error-prone. <ref>[http://en.wikipedia.org/wiki/Macro_(computer_science) Wikipedia Entry on Macro]</ref>


In dynamically typed languages, the variables and parameters do not have a designated type and may take different values at different times. In all the operations, the operands must be type checked at run-time just before performing the operation. Dynamically typed languages don’t need to make a distinction between classes created at compile time and classes providedIt is possible to define classes at run time and in fact, classes are always defined at run time. These eliminate many developer constraints by avoiding the need of book keeping, declarations etc. Due to this flexibility these languages make an ideal candidate for prototyping and are widely used in agile development environments. However, dynamic languages are known to have performance issues. Static languages have code optimization features at compile time, but dynamic languages allow run-time code optimizations only. [http://www.slideshare.net/aminbandeali/dynamically-and-statically-typed-languages] In dynamically typed languagesthe interpreter deduces type and type conversions, this makes development time faster, but it also can provoke run-time failures. These run-time failures are caught early on during compile time for statically typed languages.
Example of macro in C programming language
#include <stdio.h>
  #define debug_print(...) \
    if (DEBUG) fprintf(stderr, __VA_ARGS__)
int main() {
    debug_print("debug\n");
  }


at compile time the compiler will replace the macro
debug_print("debug\n");
with
if(DEBUG) printf(stderr,"debug\n");


Examples of dynamically typed languages:
== Introduction to Dynamically Typed Programming Languages ==
* Perl
* Python
* JavaScript
* PHP
* Ruby
* SmallTalk


= Implementation of Metaprograming in Dynamiclly Typed Languages =
In general programming languages can be split into two categories base on their [http://en.wikipedia.org/wiki/Type_system type system], [http://en.wikipedia.org/wiki/Type_system#Static_typing statically typed] and [http://en.wikipedia.org/wiki/Type_system#Dynamic_typing dynamically typed]. A programming language is said to be statically typed if type checking is performed during compile-time. In comparison, a programming language is said to be dynamically typed deferring type checking until run-time as opposes to compile-time. <ref>[http://en.wikipedia.org/wiki/Type_system Wikipedia Entry on Type System]</ref>




In dynamically typed languages, the variables and parameters do not have a designated type and may take different type of values at different times. In all the operations, the operands must be type checked at run-time just before performing the operation. Dynamically typed languages don’t need to make a distinction between classes created at compile time and classes provided.  It is possible to define classes at run time and in fact, classes are always defined at run time. These eliminate many developer constraints by avoiding the need of book keeping, declarations etc. Due to this flexibility these languages make an ideal candidate for prototyping and are widely used in agile development environments. However, dynamic languages are known to have performance issues. Static languages have code optimization features at compile time, but dynamic languages allow run-time code optimizations only. <ref>[http://www.slideshare.net/aminbandeali/dynamically-and-statically-typed-languages CPSC 543 Dynamically and Statically typed Languages June 10, 2009 By Muhammad Bandeali]</ref> In dynamically typed languages,  the interpreter deduces type and type conversions, this makes development time faster, but it also can provoke run-time failures. These run-time failures are caught early on during compile time for statically typed languages.


== Shell Script ==
== Examples of Dynamically Typed Programming Languages ==
A [http://en.wikipedia.org/wiki/Shell_script shell script] is a script written for command line interpreter of an operating system.
=== Perl ===
Perl is a high-level, general-purpose, interpreted, dynamic programming language originally developed as a general-purpose Unix scripting language to make report processing easier. Perl borrows features from other programming languages including C, shell scripting (sh), AWK, and sed. The language provides powerful text processing facilities without the arbitrary data-length limits of many contemporary Unix tools, facilitating easy manipulation of text files. Perl is used for CGI scripting, graphics programming, system administration, network programming, finance, bioinformatics, and other applications.<ref>[http://en.wikipedia.org/wiki/Perl Wikipedia Entry on Perl]</ref>


In the simplest form shell script can be use for metaprogramming by generating or source code or modifying than recompiling a existing program.
=== Python ===
Python is a general-purpose, high-level programming language whose design philosophy emphasizes code readability. It supports multiple programming paradigms, including object-oriented, imperative and functional programming styles. It features a fully dynamic type system and automatic memory management, similar to that of Scheme, Ruby, Perl and Tcl. Like other dynamic languages, Python is often used as a scripting language, but is also used in a wide range of non-scripting contexts. Using third-party tools, Python code can be packaged into standalone executable programs.<ref>[http://en.wikipedia.org/wiki/Python_(programming_language) Wikipedia Entry on Python]</ref>


for example
=== Ruby ===
Ruby is a dynamic, reflective, general-purpose object-oriented programming language that combines syntax inspired by Perl with Smalltalk-like features. It was also influenced by Eiffel and Lisp. Ruby supports multiple programming paradigms, including functional, object oriented, imperative and reflective. It also has a dynamic type system and automatic memory management; it is therefore similar in varying respects to Smalltalk, Python, Perl, Lisp, Dylan, Pike, and CLU.<ref>[http://en.wikipedia.org/wiki/Ruby_(programming_language) Wikipedia Entry on Ruby]</ref>


== Ruby ==
Ruby is a dynamic, reflective, general-purpose object-oriented programming language that combines syntax inspired by Perl with Smalltalk-like features. It was also influenced by Eiffel and Lisp[8]. Ruby was first designed and developed in the mid-1990s by Yukihiro "Matz" Matsumoto in Japan.




=== Example of metaprograming in Ruby ===
== Example of Meta-Programming in Dynamically Typed Languages ==
In ruby you can write methods using metaprogramming to insert code into the program.


A widely use example of such metaprogramming method is the attr_accessor method in the class named Module
=== Ruby ===
In ruby you can write methods using meta-programming to insert code into the program. A widely use example of such meta-programming method is the attr_accessor method in the class named Module.


In this example attr_accessor method is use to insert the accessor codes to the class
In this example attr_accessor method is use to insert the accessor codes to the class
Line 75: Line 103:
   end
   end
  end
  end


The method method_missing() is another example of metaprograming in Ruby.
The method method_missing() is another example of metaprograming in Ruby.
In ruby if the interpreter can’t find the method anywhere up the object’s chain of inheritance, it will go back to the object and call the method named method_missing(). The interpreter looks for method_missing() in the object’s methods and up the object’s chain of inheritance until it reaches the Object class where method_missing() is defined.
In ruby if the interpreter can’t find the method anywhere up the object’s chain of inheritance, it will go back to the object and call the method named method_missing(). The interpreter looks for method_missing() in the object’s methods and up the object’s chain of inheritance until it reaches the Object class where method_missing() is defined.


 
  class MyClass
  class MyClass
   def method_missing(name, *args)
   def method_missing(name, *args)
Line 91: Line 117:
  m.another_undefined_method("three", "four") # => another_undefined_method was called with arguments: three, four
  m.another_undefined_method("three", "four") # => another_undefined_method was called with arguments: three, four


The class MyClass does not have a method named undefined_method() or another_underfined_method() but the method_missing() method created responds to these methods
The class MyClass does not have a method named undefined_method() or another_underfined_method() but the method_missing() method created responds to these methods.
 
 
=== Python ===
Example of meta-programming in Python using [http://wiki.python.org/moin/PythonDecorators#WhatisaDecorator PythonDecorators]. <ref>[http://www.ibm.com/developerworks/linux/library/l-cpdecor/index.html Charming Python: Decorators make magic easy]</ref>
def elementwise(fn):
    def newfn(arg):
        if hasattr(arg,'__getitem__'):  # is a Sequence
            return type(arg)(map(fn, arg))
        else:
            return fn(arg)
    return newfn
@elementwise
def compute(x):
    return x**3 - 1
print compute(5)        # => prints: 124
print compute([1,2,3])  # => prints: [0, 7, 26]
print compute((1,2,3))  # => prints: (0, 7, 26)
 
=== Perl ===
Example of meta-programming in [http://en.wikipedia.org/wiki/Perl_6 Perl 6] using ^add_method. <ref>[http://transfixedbutnotdead.com/2010/01/14/anyone-for-perl-6-metaprogramming/ Anyone for Perl 6 metaprogramming?]</ref>
use v6;
class Ninja {
    has Str $.name is rw;
}
my Ninja $drew .= new( name => 'Drew' );
my Ninja $adam .= new( name => 'Adam' );
 
# REOPEN NINJA CLASS ("IS ALSO" DOES THE BIZ)
# AND ADD 'BATTLE_CRY' METHOD
class Ninja is also { 
    method battle_cry {
        say $.name ~ ' says zing!!!';
    }
}
$drew.battle_cry;  # => DREW SAYS ZING!!!
$adam.battle_cry;  # => ADAM SAYS ZING!!!
 
# ADD 'THROW_STAR' METHOD TO $DREW OBJECT BY CREATING
# AND APPLYING ("DOES") ROLE TO IT (SINGLETON METHOD)
role ThrowStar {
    method throw_star { say "throwing star" }
}
$drew does ThrowStar;
$drew.throw_star;    # => THROWING A STAR
 
# CALL METHOD DYNAMICALLY: $OBJ.'METHOD_NAME' OR $OBJ.$METHOD
$drew.'battle_cry';    # => DREW SAYS ZING!!!
 
# ADD "COLOUR" METHOD CLOSING OVER $COLOUR_NAME (IE. CLOSURE):
my $colour_name = 'black';
class Ninja is also {
    method colour { say "{$.name}'s colour is {$colour_name} " }
}
$drew.colour;    # => DREW'S COLOUR IS BLACK
$adam.colour;    # => ADAM'S COLOUR IS BLACK
 
# "DEFINING A METHOD DYNAMICALLY ON AN INSTANCE THAT CLOSES
# OVER LOCAL SCOPE AND ACCESSES THE INSTANCE’S STATE"
my $sword_symbol = '********';
$drew.^add_method( 'swing', method ( Str $sound_effect ) {
    say "{$.name}: {$sword_symbol} {$sound_effect}";
});
$drew.swing( 'slash!!' );    # => DREW: ********* SLASH!!
 
== Meta-Programming Feature in Dynamically Typed Languages ==
 
=== Reflection ===
[http://en.wikipedia.org/wiki/Reflection_(computer_science) Reflection] is the ability of a computer program to examine (introspection) and modify the structure, meta-data and behavior of an object at runtime.<ref>[http://en.wikipedia.org/wiki/Reflection_(computer_science) Wikipedia Entry on Reflection]</ref>


= References =
Example of introspection in ruby
ruby-1.8.7-p352 :012 > 1.object_id
=> 3
ruby-1.8.7-p352 :013 > 1.class
=> Fixnum
ruby-1.8.7-p352 :014 > 1.methods
=> [:to_s, :-@, :+, :-, :*, :/, :div,
    :%, :modulo, :divmod, :fdiv, :**, :abs,
    :magnitude, :==, :===, :<=>, :>, :>=, :<,
    :<=, :~, :&, :|, :^, :[], :<<, :>>, :to_f,
    :size, :zero?, :odd?, :even?, :succ, :integer?,
    :upto, :downto, :times, :next, :pred, :chr, :ord,
    :to_i, :to_int, :floor, :ceil, :truncate, :round,
    :gcd, :lcm, :gcdlcm, :numerator, :denominator, ...]
 
 
"eval" are type of methods that allow the program to evaluate arbitrary code in the context of a particular class or object. <ref>[http://www.jimmycuadra.com/posts/metaprogramming-ruby-class-eval-and-instance-eval Metaprogramming Ruby: class_eval and instance_eval]</ref> They are examples of the reflective nature of in dynamically type languages
 
In ruby eval allow us to define method for a class outside of the class without reopening the class
For example:
class Person
end
Person.class_eval do
  def say_hello
  "Hello!"
  end
end
The block of code
  def say_hello
  "Hello!"
  end
pass to class_eval is evaluated in the context of that class.
In this example it is use to define a instance method within the class Person.


*[1] [http://en.wikipedia.org/wiki/Metaprogramming Wikipedia Entry on Metaprogramming]
  Hao= Person.new
*[2]  [http://en.wikipedia.org/wiki/Dynamic_programming_language Wikipedia Entry on Dynamic programming language]
  Hao.say_hello # "Hello!"
*[3]  [http://en.wikipedia.org/wiki/Type_system Wikipedia Entry on Type System]
*[4] [http://en.wikipedia.org/wiki/Shell_script Wikipedia Entry on Shell script]
*[5]  [http://en.wikipedia.org/wiki/Ruby_(programming_language) Wikipedia Entry on Shell script]


*[6] [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2010/ch2_S24_rm Expertiza Wiki Entry on Metaprogramming in Statically Typed Languages 1]
= Reference =
*[7] [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2010/ch2_S24_NS Expertiza Wiki Entry on Metaprogramming in Statically Typed Languages 2]
<references/>
*[8] [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2010/ch2_S24_sk Expertiza Wiki Entry on Metaprogramming in What is Metaprogramming]

Latest revision as of 04:27, 26 February 2013


"I rather write a x86 program in binary using a butterfly than writing this article" - Hao Liu

This page is a discuss about meta-programming and its implementation and uses in dynamically typed languages.

Meta-programming in Dynamically Typed Languages

Introduction to Meta-Programming

In essence meta-programs are computer programs that can write or manipulate other programs or themselves as their data. Meta-programming is the general term for techniques use to write such program. The language in which the meta-program is written is called the metalanguage. The language of the programs that are manipulated is called the object language.<ref>Wikipedia Entry on Metaprogramming</ref>


This simplistic definition of meta-program and meta-programming tend to give reader a very intimidating first impression and render a image of a sentient self modifying program that ultimately take over the world. In reality meta-program and meta-programming techniques can very in complexity from the extreme of sentient self modifying program to simple and everyday thing such as a pre-processor macro. In most cases meta-programming are use to improve the quality of life of the programmer by improving the readability and re-usability of the code and by providing a higher level of abstraction.

Example of Meta-Programming

This section describe some of diffident types of meta-programming techniques and example of their usage.

Generative Programming

Generative programming is a style of computer programming that uses automated source code creation through generic frames, classes, prototypes, templates, aspects, and code generators to improve programmer productivity.<ref>Wikipedia Entry on Automatic Programming</ref>

In its simplest form any programming language, even the shell script, can be use for this type of meta-programming, so long as they have the ability to reading and modifying the source code of another program or it's own source code as a text file.

For example:

#!/usr/bin/env bash
echo -e "#include <stdio.h>" >> program.c
echo -e "int main() {"       >> program.c
for ((I=1; I<=5; I++)) do
    echo -e "  printf(\042 meta \042);" >> program.c
done
echo -e "return 0}" >> program.c
g++ program.c
a.out

This simple bash script generates a program that prints out

meta meta meta meta meta

by generating a c source code as a text file, than compile to source code into a executable binary file using a compiler.

Template Meta-Programming

Template meta-programming is a meta-programming technique in which templates are used by a compiler to generate temporary source code, which is merged by the compiler with the rest of the source code and then compiled. The output of these templates include compile-time constants, data structures, and complete functions. The use of templates can be thought of as compile-time execution.<ref>Wikipedia Entry on Template Metaprogramming</ref>

A example usage of template programming is to pre-generate tables of data at compile time for use at runtime. For example, if you are writing a game that require lots of calculation of sine of 8 bit integers, instead of calculating sine at run time when they are needed, template programming can be use to build a static data tables as pre-calculated value at compile-time to eliminate the need of recalculating sine each time.<ref>art of metaprogramming, Part 1: Introduction to metaprogramming</ref>

Macros

A macro is a rule or pattern that specifies how a certain input sequence (often a sequence of characters) should be mapped to a replacement input sequence (also often a sequence of characters) according to a defined procedure. The mapping process that instantiates (transforms) a macro use into a specific sequence is known as macro expansion. Macros are used to make a sequence of computing instructions available to the programmer as a single program statement, making the programming task less tedious and less error-prone. <ref>Wikipedia Entry on Macro</ref>

Example of macro in C programming language

#include <stdio.h>
#define debug_print(...) \
   if (DEBUG) fprintf(stderr, __VA_ARGS__)
int main() {
    debug_print("debug\n");
}

at compile time the compiler will replace the macro

debug_print("debug\n"); 

with

if(DEBUG) printf(stderr,"debug\n");

Introduction to Dynamically Typed Programming Languages

In general programming languages can be split into two categories base on their type system, statically typed and dynamically typed. A programming language is said to be statically typed if type checking is performed during compile-time. In comparison, a programming language is said to be dynamically typed deferring type checking until run-time as opposes to compile-time. <ref>Wikipedia Entry on Type System</ref>


In dynamically typed languages, the variables and parameters do not have a designated type and may take different type of values at different times. In all the operations, the operands must be type checked at run-time just before performing the operation. Dynamically typed languages don’t need to make a distinction between classes created at compile time and classes provided. It is possible to define classes at run time and in fact, classes are always defined at run time. These eliminate many developer constraints by avoiding the need of book keeping, declarations etc. Due to this flexibility these languages make an ideal candidate for prototyping and are widely used in agile development environments. However, dynamic languages are known to have performance issues. Static languages have code optimization features at compile time, but dynamic languages allow run-time code optimizations only. <ref>CPSC 543 Dynamically and Statically typed Languages June 10, 2009 By Muhammad Bandeali</ref> In dynamically typed languages, the interpreter deduces type and type conversions, this makes development time faster, but it also can provoke run-time failures. These run-time failures are caught early on during compile time for statically typed languages.

Examples of Dynamically Typed Programming Languages

Perl

Perl is a high-level, general-purpose, interpreted, dynamic programming language originally developed as a general-purpose Unix scripting language to make report processing easier. Perl borrows features from other programming languages including C, shell scripting (sh), AWK, and sed. The language provides powerful text processing facilities without the arbitrary data-length limits of many contemporary Unix tools, facilitating easy manipulation of text files. Perl is used for CGI scripting, graphics programming, system administration, network programming, finance, bioinformatics, and other applications.<ref>Wikipedia Entry on Perl</ref>

Python

Python is a general-purpose, high-level programming language whose design philosophy emphasizes code readability. It supports multiple programming paradigms, including object-oriented, imperative and functional programming styles. It features a fully dynamic type system and automatic memory management, similar to that of Scheme, Ruby, Perl and Tcl. Like other dynamic languages, Python is often used as a scripting language, but is also used in a wide range of non-scripting contexts. Using third-party tools, Python code can be packaged into standalone executable programs.<ref>Wikipedia Entry on Python</ref>

Ruby

Ruby is a dynamic, reflective, general-purpose object-oriented programming language that combines syntax inspired by Perl with Smalltalk-like features. It was also influenced by Eiffel and Lisp. Ruby supports multiple programming paradigms, including functional, object oriented, imperative and reflective. It also has a dynamic type system and automatic memory management; it is therefore similar in varying respects to Smalltalk, Python, Perl, Lisp, Dylan, Pike, and CLU.<ref>Wikipedia Entry on Ruby</ref>


Example of Meta-Programming in Dynamically Typed Languages

Ruby

In ruby you can write methods using meta-programming to insert code into the program. A widely use example of such meta-programming method is the attr_accessor method in the class named Module.

In this example attr_accessor method is use to insert the accessor codes to the class

class MyClass   
  attr_accessor :info
end

Is the same as

class MyClass
 def variable=(value)
   @variable = value
 end
 def variable
   @variable
 end
end

The method method_missing() is another example of metaprograming in Ruby. In ruby if the interpreter can’t find the method anywhere up the object’s chain of inheritance, it will go back to the object and call the method named method_missing(). The interpreter looks for method_missing() in the object’s methods and up the object’s chain of inheritance until it reaches the Object class where method_missing() is defined.

class MyClass
  def method_missing(name, *args)
    puts "#{name} was called with arguments: #{args.join(', ')}"
  end
end
m = MyClass.new
m.undefined_method("one", "two") # => undefined_method was called with arguments: one, two
m.another_undefined_method("three", "four") # => another_undefined_method was called with arguments: three, four

The class MyClass does not have a method named undefined_method() or another_underfined_method() but the method_missing() method created responds to these methods.


Python

Example of meta-programming in Python using PythonDecorators. <ref>Charming Python: Decorators make magic easy</ref>

def elementwise(fn):
   def newfn(arg):
       if hasattr(arg,'__getitem__'):  # is a Sequence
           return type(arg)(map(fn, arg))
       else:
           return fn(arg)
   return newfn
@elementwise
def compute(x):
   return x**3 - 1

print compute(5)        # => prints: 124
print compute([1,2,3])  # => prints: [0, 7, 26]
print compute((1,2,3))  # => prints: (0, 7, 26)

Perl

Example of meta-programming in Perl 6 using ^add_method. <ref>Anyone for Perl 6 metaprogramming?</ref>

use v6;
class Ninja {
   has Str $.name is rw;
}
my Ninja $drew .= new( name => 'Drew' );
my Ninja $adam .= new( name => 'Adam' );
# REOPEN NINJA CLASS ("IS ALSO" DOES THE BIZ)
# AND ADD 'BATTLE_CRY' METHOD
class Ninja is also {   
   method battle_cry {
       say $.name ~ ' says zing!!!';
   }
}
$drew.battle_cry;   # => DREW SAYS ZING!!!
$adam.battle_cry;   # => ADAM SAYS ZING!!!
# ADD 'THROW_STAR' METHOD TO $DREW OBJECT BY CREATING
# AND APPLYING ("DOES") ROLE TO IT (SINGLETON METHOD)
role ThrowStar {
   method throw_star { say "throwing star" }
}
$drew does ThrowStar;
$drew.throw_star;     # => THROWING A STAR
# CALL METHOD DYNAMICALLY: $OBJ.'METHOD_NAME' OR $OBJ.$METHOD
$drew.'battle_cry';     # => DREW SAYS ZING!!!
# ADD "COLOUR" METHOD CLOSING OVER $COLOUR_NAME (IE. CLOSURE):
my $colour_name = 'black';
class Ninja is also {
   method colour { say "{$.name}'s colour is {$colour_name} " }
}
$drew.colour;    # => DREW'S COLOUR IS BLACK
$adam.colour;    # => ADAM'S COLOUR IS BLACK
# "DEFINING A METHOD DYNAMICALLY ON AN INSTANCE THAT CLOSES
# OVER LOCAL SCOPE AND ACCESSES THE INSTANCE’S STATE"
my $sword_symbol = '********';
$drew.^add_method( 'swing', method ( Str $sound_effect ) {
   say "{$.name}: {$sword_symbol} {$sound_effect}";
});
$drew.swing( 'slash!!' );    # => DREW: ********* SLASH!!

Meta-Programming Feature in Dynamically Typed Languages

Reflection

Reflection is the ability of a computer program to examine (introspection) and modify the structure, meta-data and behavior of an object at runtime.<ref>Wikipedia Entry on Reflection</ref>

Example of introspection in ruby

ruby-1.8.7-p352 :012 > 1.object_id
=> 3
ruby-1.8.7-p352 :013 > 1.class
=> Fixnum
ruby-1.8.7-p352 :014 > 1.methods
=> [:to_s, :-@, :+, :-, :*, :/, :div, 
    :%, :modulo, :divmod, :fdiv, :**, :abs, 
    :magnitude, :==, :===, :<=>, :>, :>=, :<, 
    :<=, :~, :&, :|, :^, :[], :<<, :>>, :to_f, 
    :size, :zero?, :odd?, :even?, :succ, :integer?, 
    :upto, :downto, :times, :next, :pred, :chr, :ord, 
    :to_i, :to_int, :floor, :ceil, :truncate, :round, 
    :gcd, :lcm, :gcdlcm, :numerator, :denominator, ...]


"eval" are type of methods that allow the program to evaluate arbitrary code in the context of a particular class or object. <ref>Metaprogramming Ruby: class_eval and instance_eval</ref> They are examples of the reflective nature of in dynamically type languages

In ruby eval allow us to define method for a class outside of the class without reopening the class For example:

class Person
end
Person.class_eval do
 def say_hello
  "Hello!"
 end
end

The block of code

 def say_hello
  "Hello!"
 end

pass to class_eval is evaluated in the context of that class. In this example it is use to define a instance method within the class Person.

Hao= Person.new
Hao.say_hello # "Hello!"

Reference

<references/>