CSC/ECE 517 Fall 2010/ch4 4g HW: Difference between revisions
No edit summary |
|||
Line 58: | Line 58: | ||
'''Ruby''' | '''Ruby''' | ||
Let's consider how we might implement our append_song method from above using metaprogramming techniques to create its superclass and then dynamically define the method itself. | |||
info = Class.new | |||
info .class_eval do | |||
define_method: append_song do | |||
self << self.title << " (" << self.artist << ")" | |||
end | |||
c.new.append_song | |||
'''Python''' | '''Python''' |
Revision as of 02:44, 20 October 2010
Introduction
Drawing from the concepts discussed in Chapter 2 Section 24, Metaprogramming in Statically Typed Languages, we will continue to examine metaprogramming concepts in the environment of dynamically typed languages. As always, the focus will be on object-oriented languages to demonstrate the common usages of metaprogramming.
As you may recall from the previous chapter, metaprogramming can be defined as "the technique that allows us to write programs that can manipulate other programs or themselves as a part of their data" [[1]]. Thus it allows us to add behavior to classes or objects that was not previously specified, often done at compile time instead of runtime. The same basic concepts still apply here, although in a few different fashions for dynamically typed languages instead of those that are statically typed.
This chapter will begin with a brief overview of object-oriented dynamic programming languages, or languages with an object-oriented bent, and progress into a further analysis of dynamic typing within those dynamic languages. The majority of the chapter will then cover metaprogramming within the previous described environment, offering examples, common methods of use, and existence in real-world software projects. Examples will be given to illustrate important concepts, and will be expressed in sample object-oriented dynamically typed languages.
Dynamic Languages
Dynamic programming languages are loosely defined as languages that are designed to exhibit, or provide as extra functionality, behaviors at run-time that are otherwise normally found at compile-time. This difference from static languages is exemplified in behaviors such as (during execution) adding new methods, classes or objects, extending existing classes or objects, and modifying the type system [[2]].
Common and useful examples of object-oriented dynamic languages include Ruby, Python, and Perl.
Ruby: Ruby is considered a pure object-oriented dynamic language with dynamic typing.
Python: Python is not technically (by definition) purely object-oriented, but it was designed mainly for such purposes, is dynamic and dynamically typed, and so is relevant to our discussions.
Perl: Perl is not completely object-oriented, but has essential object-oriented elements. It was designed as procedural but has since been extended to implement object-oriented mentalities, and is also dynamic and dynamically typed.
Dynamic Typing
Most but not all dynamic programming languages are also dynamically typed. Dynamic typing describes the method of type checking that occurs mainly at run-time, instead of compile-time. Put simply, the type of a variable is not statically defined; instead, a variable refers to a value, and only the value has a strict type [[3]]. This enables a more fluid style of programming, especially in areas like metaprogramming as we soon shall see.
Example
Duck typing is a well-known and interesting form of dynamic typing that appears prominently in Ruby. Here, the type of the object is ignored in favor of the usable aspects of an object. As is often said, "if it walks like a duck, and quacks like a duck, then it is a duck" [[4]]. Suppose we wanted to code the concatenation of information about a song to a string. Without duck typing, we might write it as:
def append_song(result, song) # test we're given the right parameters unless result.kind_of?(String) fail TypeError.new("String expected") end unless song.kind_of?(Song) fail TypeError.new("Song expected") end result << song.title << " (" << song.artist << ")" end result = "" append_song(result, song) # => "I Got Rhythm (Gene Kelly)"
This sort of tedious checking need not really be done. If whatever object is passed in 'song' responds to .title and .artist, then things will be alright. If not, the exceptions will be thrown anyway, regardless of if we're explicitly checked and then failed. Thus duck typing enables us to more succinctly write [[5]]:
def append_song(result, song) result << song.title << " (" << song.artist << ")" end result = "" append_song(result, song) # => "I Got Rhythm (Gene Kelly)"
Metaprogramming
Now that we've established clearly what dynamic programming languages that use dynamic typing are, and shown a typical example of how this appears in simple code, we can immerse ourselves further into the more complex arena of metaprogramming with these kinds of languages.
Definition.
How the implementation is similar to or different from static.
Common Usage
Examples
Ruby Let's consider how we might implement our append_song method from above using metaprogramming techniques to create its superclass and then dynamically define the method itself.
info = Class.new info .class_eval do define_method: append_song do self << self.title << " (" << self.artist << ")" end c.new.append_song
Python
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
Impact and Development
Real-world examples.
Proposed improvements in the given language-examples.
Summary
Review everything.
References
[1] CSC/ECE 517 Fall 2010/ch2 S24 NS . http://pg-server.csc.ncsu.edu/mediawiki/index.php/CSC/ECE_517_Fall_2010/ch2_S24_NS#What_is_Metaprogramming.3F.
[2] http://en.wikipedia.org/wiki/Dynamic_programming_language.
[3] http://en.wikipedia.org/wiki/Dynamic_typing#Dynamic_typing
[4] http://en.wikipedia.org/wiki/Dynamic_typing#Duck_typing
[5] Pragmatic Ruby 1.9, p.375.