. Python & IronPython . An introduction to Python and using IronPython on the .NET Framework

Rasmus Nielsen ([email protected])

IT University of Copenhagen

March 1, 2010

...... Rasmus Nielsen ([email protected]) Python & IronPython What is Python?

Python is named in honour of Python is an interpreted, dynamically typed, high-level language Python combines remarkable power with very clean, clear, and spare syntax Python is a multi-paradigm language supporting: Object-oriented programming Procedural programming Aspect-oriented programming Functional programming Metaprogramming

...... Rasmus Nielsen ([email protected]) Python & IronPython Similarities to and

Typically compiled to , but compilation is implicit Everything inherits from “object” INCLUDING: numbers functions classes . . . – everything is “first-class” Vast, powerful standard Garbage collection Introspection / reflection Parametric polymorphism (Generics) Threads . . .

...... Rasmus Nielsen ([email protected]) Python & IronPython Similaries to C

The Spirit of C ..1. Trust the . ..2. Dont prevent the programmer from doing what needs to be done. ..3. Keep the language small and simple. ..4. Provide only one way to do an operation. ..5. Make it fast, even if it is not guaranteed to be portable.

Rationale for International Standard Programming Languages – C

Ad 5: Python is not intrinsically fast but IronPython is!

...... Rasmus Nielsen ([email protected]) Python & IronPython Python vs C/C++/Java/C♯

Easy to learn, easy to teach No notion of private, public, and sealed, etc. Typing: strong, but dynamic Names have no type Objects have types No "declarations" – just statements Spare syntax, minimal ornamentation: No { } for blocks, just indentation No ( ) for if/while conditions Generally less punctuation – no “;” Everything is “first-class”: object classes, functions, methods, modules

...... Rasmus Nielsen ([email protected]) Python & IronPython Python extended

Look, Ma! Python can do a lot more:

Built in support for complex numbers (like Fortran!) Multiple paradigms (OOP, procedural, generic, some functional) Multiple inheritance (like C++) Tuples (like SML) Multiple return values (forget about ref and out) Dynamically typed (like Ruby and JavaScript) Duck typing

...... Rasmus Nielsen ([email protected]) Python & IronPython Implementations

TM CPython (C, , 1991) JPython −→ (Java, , 1997)

IronPython (C♯, Jim Hugunin, 2006) PyPy (Python(!) 2007)

...... Rasmus Nielsen ([email protected]) Python & IronPython Jim Huginin – creator of Jython – sets out to prove this 6 weeks pass Project fails – PyStone benchmark shows IronPython is 1.7 times faster than CPython 2004: Jim feels obligated to continue the work and eventually demonstrates the first version to Microsoft hires him right away! ·· v1.0 (2006) ·· v2.0 (2008) ·· v2.6 (2009) ¹ The built for IronPython and IronRuby is injected into vNext of the CLR and C♯ 4.0 IronPython vNext will be released 1-2 months after .NET 4.0 (v2.6 and v3.1 language compatibility)

The story of IronPython

2003: “Fact”: the sucks regarding dynamic languages

...... Rasmus Nielsen ([email protected]) Python & IronPython 6 weeks pass Project fails – PyStone benchmark shows IronPython is 1.7 times faster than CPython 2004: Jim feels obligated to continue the work and eventually demonstrates the first version to Microsoft Microsoft hires him right away! ·· v1.0 (2006) ·· v2.0 (2008) ·· v2.6 (2009) ¹ The Dynamic Language Runtime built for IronPython and IronRuby is injected into vNext of the CLR and C♯ 4.0 IronPython vNext will be released 1-2 months after .NET 4.0 (v2.6 and v3.1 language compatibility)

The story of IronPython

2003: “Fact”: the Common Language Runtime sucks regarding dynamic languages Jim Huginin – creator of Jython – sets out to prove this

...... Rasmus Nielsen ([email protected]) Python & IronPython Project fails – PyStone benchmark shows IronPython is 1.7 times faster than CPython 2004: Jim feels obligated to continue the work and eventually demonstrates the first version to Microsoft Microsoft hires him right away! ·· v1.0 (2006) ·· v2.0 (2008) ·· v2.6 (2009) ¹ The Dynamic Language Runtime built for IronPython and IronRuby is injected into vNext of the CLR and C♯ 4.0 IronPython vNext will be released 1-2 months after .NET 4.0 (v2.6 and v3.1 language compatibility)

The story of IronPython

2003: “Fact”: the Common Language Runtime sucks regarding dynamic languages Jim Huginin – creator of Jython – sets out to prove this 6 weeks pass

...... Rasmus Nielsen ([email protected]) Python & IronPython 2004: Jim feels obligated to continue the work and eventually demonstrates the first version to Microsoft Microsoft hires him right away! ·· v1.0 (2006) ·· v2.0 (2008) ·· v2.6 (2009) ¹ The Dynamic Language Runtime built for IronPython and IronRuby is injected into vNext of the CLR and C♯ 4.0 IronPython vNext will be released 1-2 months after .NET 4.0 (v2.6 and v3.1 language compatibility)

The story of IronPython

2003: “Fact”: the Common Language Runtime sucks regarding dynamic languages Jim Huginin – creator of Jython – sets out to prove this 6 weeks pass Project fails – PyStone benchmark shows IronPython is 1.7 times faster than CPython

...... Rasmus Nielsen ([email protected]) Python & IronPython Microsoft hires him right away! ·· v1.0 (2006) ·· v2.0 (2008) ·· v2.6 (2009) ¹ The Dynamic Language Runtime built for IronPython and IronRuby is injected into vNext of the CLR and C♯ 4.0 IronPython vNext will be released 1-2 months after .NET 4.0 (v2.6 and v3.1 language compatibility)

The story of IronPython

2003: “Fact”: the Common Language Runtime sucks regarding dynamic languages Jim Huginin – creator of Jython – sets out to prove this 6 weeks pass Project fails – PyStone benchmark shows IronPython is 1.7 times faster than CPython 2004: Jim feels obligated to continue the work and eventually demonstrates the first version to Microsoft

...... Rasmus Nielsen ([email protected]) Python & IronPython ·· v1.0 (2006) ·· v2.0 (2008) ·· v2.6 (2009) ¹ The Dynamic Language Runtime built for IronPython and IronRuby is injected into vNext of the CLR and C♯ 4.0 IronPython vNext will be released 1-2 months after .NET 4.0 (v2.6 and v3.1 language compatibility)

The story of IronPython

2003: “Fact”: the Common Language Runtime sucks regarding dynamic languages Jim Huginin – creator of Jython – sets out to prove this 6 weeks pass Project fails – PyStone benchmark shows IronPython is 1.7 times faster than CPython 2004: Jim feels obligated to continue the work and eventually demonstrates the first version to Microsoft Microsoft hires him right away!

...... Rasmus Nielsen ([email protected]) Python & IronPython The Dynamic Language Runtime built for IronPython and IronRuby is injected into vNext of the CLR and C♯ 4.0 IronPython vNext will be released 1-2 months after .NET 4.0 (v2.6 and v3.1 language compatibility)

The story of IronPython

2003: “Fact”: the Common Language Runtime sucks regarding dynamic languages Jim Huginin – creator of Jython – sets out to prove this 6 weeks pass Project fails – PyStone benchmark shows IronPython is 1.7 times faster than CPython 2004: Jim feels obligated to continue the work and eventually demonstrates the first version to Microsoft Microsoft hires him right away! ·· v1.0 (2006) ·· v2.0 (2008) ·· v2.6 (2009) ¹

...... Rasmus Nielsen ([email protected]) Python & IronPython IronPython vNext will be released 1-2 months after .NET 4.0 (v2.6 and v3.1 language compatibility)

The story of IronPython

2003: “Fact”: the Common Language Runtime sucks regarding dynamic languages Jim Huginin – creator of Jython – sets out to prove this 6 weeks pass Project fails – PyStone benchmark shows IronPython is 1.7 times faster than CPython 2004: Jim feels obligated to continue the work and eventually demonstrates the first version to Microsoft Microsoft hires him right away! ·· v1.0 (2006) ·· v2.0 (2008) ·· v2.6 (2009) ¹ The Dynamic Language Runtime built for IronPython and IronRuby is injected into vNext of the CLR and C♯ 4.0

...... Rasmus Nielsen ([email protected]) Python & IronPython The story of IronPython

2003: “Fact”: the Common Language Runtime sucks regarding dynamic languages Jim Huginin – creator of Jython – sets out to prove this 6 weeks pass Project fails – PyStone benchmark shows IronPython is 1.7 times faster than CPython 2004: Jim feels obligated to continue the work and eventually demonstrates the first version to Microsoft Microsoft hires him right away! ·· v1.0 (2006) ·· v2.0 (2008) ·· v2.6 (2009) ¹ The Dynamic Language Runtime built for IronPython and IronRuby is injected into vNext of the CLR and C♯ 4.0 IronPython vNext will be released 1-2 months after .NET 4.0 (v2.6 and v3.1 language compatibility) ...... Rasmus Nielsen ([email protected]) Python & IronPython Why IronPython

Reasons that CPython might be interested in IronPython include: Corporate credibility (introducing new technologies can be very difficult in some companies, if .NET is already established then you may need no excuse to start using IronPython) No GlobalInterpreterLock – IronPython has no GIL and multi-threaded code can use multi core processors The .NET framework library is very big. Particularly the user interface library is very good. IronPython is easy to embed in .NET applications as a scripting language Easier to extend than CPython (C♯ is memory managed and C♯ types can be used directly in IronPython with no wrapping) Silverlight! (Die, ActionScript, Die!)

Source: http://wiki.python.org/moin/IronPython!

...... Rasmus Nielsen ([email protected]) Python & IronPython The problem with object-oriented languages

“The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.”

Joe Armstrong, principal inventor of Erlang

...... Rasmus Nielsen ([email protected]) Python & IronPython The world’s smallest C♯ program – sort of. . .

Listing 1: Hello, World! in C♯

1 u s i n g System ; 2 u s i n g System . Collections . Generic ; 3 u s i n g System . Linq ; 4 u s i n g System . Text ; 5 6 namespace ConsoleApplication1 7 { 8 c l a s s Program 9 { 10 s t a t i c v o i d Main ( s t i n g [] args ) 11 { 12 Console . WriteLine ( " H e l l o , World ! " ); 13 } 14 } 15 }

...... Rasmus Nielsen ([email protected]) Python & IronPython The world’s smallest C♯ program – seriously!

Listing 2: Stripped down Hello, World! in C♯

1 c l a s s Program 2 { 3 s t a t i c v o i d Main () 4 { 5 System . Console . WriteLine ( " H e l l o , World ! " ); 6 } 7 }

...... Rasmus Nielsen ([email protected]) Python & IronPython The Python equivalent

Listing 3: Hello, World! in Python

1 p r i n t " H e l l o , World ! "

...... Rasmus Nielsen ([email protected]) Python & IronPython Duck typing

“When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.”

James Whitcomb Riley (1849-1916)

“In other words, don’t check whether it IS-a duck: check whether it QUACKS-like-a duck, WALKS-like-a duck, etc, etc, depending on exactly what subset of duck-like behaviour you need to play your language-games with.”

Alex Martelli, 2000 (Member of the Python Foundation, “Über Tech Lead” at Google, and author of “Python in a Nutshell”)

...... Rasmus Nielsen ([email protected]) Python & IronPython Duck typing in Python

Listing 4: Duck typing in Python 1 c l a s s Duck : 2 d e f quack ( self ): 3 p r i n t " Quaaaaaack ! " 4 d e f feathers ( self ): 5 p r i n t "The duck has w h i t e and g r a y f e a t h e r s . " 6 7 c l a s s Person : 8 d e f quack ( self ): 9 p r i n t "The p e r s o n i m i t a t e s a duck . " 10 d e f feathers ( self ): 11 p r i n t "The p e r s o n t a k e s a f e a t h e r from t h e ground and shows i t . " 12 13 d e f in_the_forest ( duck ): 14 duck . quack () 15 duck . feathers () 16 17 d e f game (): 18 donald = Duck () 19 john = Person () 20 in_the_forest ( donald ) 21 in_the_forest ( john ) 22 23 game ()

...... Rasmus Nielsen ([email protected]) Python & IronPython Duck typing in action

Duck typing thus allows for polymorphism without inheritance. Duck typing makes TDD a bliss - Mock objects can be done in a jiffy. Duck typing can be implemented in C♯ 4.0 using the dynamic keyword.

...... Rasmus Nielsen ([email protected]) Python & IronPython Test-Driven Development in Python

Listing 5: TDD in Python 1 import unittest 2 3 # Here ’ s our " u n i t ". 4 d e f IsOdd ( n ): 5 r e t u r n n % 2 == 1 6 7 # Here ’ s our " u n i t t e s t s ". 8 c l a s s IsOddTests ( unittest . TestCase ): 9 d e f testOne ( self ): 10 self . failUnless ( IsOdd ( 1 ) ) 11 12 d e f testTwo ( self ): 13 self . failIf ( IsOdd ( 2 ) ) 14 15 d e f main (): 16 unittest . main () 17 18 i f __name__ == ’__main__ ’ : 19 main () ...... Rasmus Nielsen ([email protected]) Python & IronPython Aspect-oriented programming

Aspect-oriented programming (AOP) is a programming paradigm in which secondary or supporting functions are isolated from the main program’s business logic. It aims to increase modularity by allowing the separation of cross-cutting concerns, forming a basis for aspect-oriented software development.

http://en.wikipedia.org/wiki/Aspect-oriented_programming

The following example is adopted from

“Pumping Iron – The State of Dynamic Languages on the .NET Framework”

by Harry Pierson (Program manager for IronPython at Microsoft))

...... Rasmus Nielsen ([email protected]) Python & IronPython Aspect-oriented programming in Python part 1

Listing 6: AOP in Python part 1

1 p r i n t " s t a r t i n g l o a d _ l o g s " 2 sw = Stopwatch . StartNew () # System . Diagnostics . Stopwatch 3 game_logs = load_logs ( file_list ) 4 sw . Stop () 5 p r i n t " l o a d _ l o g s took " , sw . Elapsed 6 7 p r i n t " s t a r t i n g load_games " 8 sw = Stopwatch . StartNew () 9 games = load_games ( game_logs ) 10 sw . Stop () 11 p r i n t " load_games took " , sw . Elapsed 12 13 p r i n t " s t a r t i n g calc_record " 14 sw = Stopwatch . StartNew () 15 games = calc_record ( games , "SEA" ) 16 sw . Stop () 17 p r i n t " calc_record took " , sw . Elapsed

...... Rasmus Nielsen ([email protected]) Python & IronPython Aspect-oriented programming in Python part 2

Listing 7: AOP in Python part 2

1 d e f timed_op ( fun , ∗args , ∗∗kwds ): 2 p r i n t " S t a r t i n g " , fun . __name__ 3 sw = Stopwatch . StartNew () 4 ret = fun (∗ args , ∗∗kwds ) 5 sw . Stop () 6 p r i n t fun . __name__ , " took " , 7 sw . Elapsed 8 r e t u r n ret

...... Rasmus Nielsen ([email protected]) Python & IronPython Aspect-oriented programming in Python part 3

Listing 8: AOP in Python part 3

1 game_logs = timed_op ( load_logs , file_list ) 2 games = timed_op ( load_games , game_logs ) 3 record = timed_op ( calc_record , games , "SEA" )

...... Rasmus Nielsen ([email protected]) Python & IronPython Aspect-oriented programming in Python part 5

Listing 9: AOP in Python part 5

1 d e f timed_op_decorator ( fun ): 2 d e f wrapper (∗ args , ∗∗kwds ): 3 p r i n t " S t a r t i n g " , fun . __name__ 4 sw = Stopwatch . StartNew () 5 ret = fun (∗ args , ∗∗kwds ) 6 sw . Stop () 7 p r i n t fun . __name__ , " took " , sw . Elapsed 8 r e t u r n ret 9 r e t u r n wrapper

...... Rasmus Nielsen ([email protected]) Python & IronPython Aspect-oriented programming in Python part 6

Listing 10: AOP in Python part 6

1 @timed_op_decorator 2 d e f load_logs ( file_names ): 3 # o m i t t e d f o r c l a r i t y 4 5 @timed_op_decorator 6 d e f load_games ( game_logs ): 7 # o m i t t e d f o r c l a r i t y 8 9 @timed_op_decorator 10 d e f calc_record ( games , team ): 11 # o m i t t e d f o r c l a r i t y

...... Rasmus Nielsen ([email protected]) Python & IronPython Aspect-oriented programming in Python part 7

Listing 11: AOP in Python part 7

1 game_logs = load_logs ( file_list ) 2 3 games = load_games ( game_logs ) 4 5 record = calc_record ( games , "SEA" )

...... Rasmus Nielsen ([email protected]) Python & IronPython Interop with statically typed .NET code (aka C♯ and VB.NET)

Listing 12: ASP.NET Membership in Python 1 import clr 2 clr . AddReference ( " System . Web . S e c u r i t y " ) 3 from System . Web . Security import Membership 4 from System . Web . Security import MembershipUser 5 6 user = Membership . CreateUser ( "RN" , " 12345678 " , ←- " r n i e @ i t u . dk" ) 7 user . IsLockedOut = true 8 Membership . UpdateUser ( user ) 9 10 users = Membership . GetAllUsers () 11 12 f o r u i n users : 13 p r i n t u . UserName DEMO http://www.trypython.org ...... Rasmus Nielsen ([email protected]) Python & IronPython Using Python as a scripting language for web applications

DEMO http://www.visitmix.com/labs/gestalt/samples/ getting.started/05_final.html

...... Rasmus Nielsen ([email protected]) Python & IronPython Numeric performance in CPython, IronPython, and C♯

Replicating “Case study 2: A division-intensive loop” from Peter Sestoft: “Numeric performance in C, C♯ and Java”:

The Poor Man’s Logarithm:

1 1 1 1 + + + ... + ≥ M (1) 1 2 3 n

...... Rasmus Nielsen ([email protected]) Python & IronPython Implementing the Poor Man’s logarithm

Listing 13: PML in C♯

1 u s i n g System ; 2 3 c l a s s Program 4 { 5 s t a t i c v o i d Main ( s t r i n g [] args ) Listing 14: PML in Python 6 { 1 M = 2 0 ; 7 i n t M = 2 0 ; 2 sum = 0 . 0 8 d o u b l e sum = 0 . 0 ; 3 n = 0 ; 9 i n t n = 0 ; 4 w h i l e sum < M : 10 5 n = n + 1 11 w h i l e ( sum < M ) 6 sum += 1 . 0 / n 12 { 13 n++; 14 sum += 1 . 0 / n ; 15 } 16 } 17 }

...... Rasmus Nielsen ([email protected]) Python & IronPython Results

C and C♯ are equivalent cf. Peter Sestoft

IronPython on par with C

CPython twice as slow as C

...... Rasmus Nielsen ([email protected]) Python & IronPython References

Books: IronPython in Action by Michael J. Foord and Christian Muirhead, Manning Publications Co 2009 Web: http://ironpython.net/ http://www.trypython.org http://www.visitmix.com/labs/gestalt/samples/ getting.started/05_final.html http://www.wingware.com/ http://www.icsharpcode.net/OpenSource/SD/ Videos: http://channel9.msdn.com/posts/martinesmann/ Pumping-Iron-Dynamic-Languages-on-NET/ http://www.youtube.com/watch?v=ujkzfC2lebA http://www.youtube.com/watch?v=E_kZDvwofHY ...... Rasmus Nielsen ([email protected]) Python & IronPython