Slideshow transcript
Slide 1: OpenLaszlo: A Python Success Story PyCon 2005 Oliver Steele Chief Software Architect Laszlo Systems, Inc. March 23, 2005
Slide 2: Lots of Languages LZX XHTML Target Languages JavaScript RELAX NG XML Definition Languages Implementation JavaCC Java Jython Python XSLT Languages Laszlo Systems, Inc. 2
Slide 3: Outline What we built OpenLaszlo platform Demos Architecture How we built it Script compiler Cool features Doc tools Synergy What we learned Technical challenges Social challenges Why it worked (and what didn’t) Laszlo Systems, Inc. 3
Slide 4: Laszlo Systems Founded in 2001 Team from Apple, Adobe, Allaire, Excite, GO, Farallon, and Macromedia 20 developers in Boston and San Francisco Bay (Looking for 21st) News October 5, 2004: Platform released as Open Source October 13, 2004: Company receives Series B funding March 2005: Earthlink announces use of Laszlo Mail Laszlo Systems, Inc. 4
Slide 5: Laszlo Vision Develop and market Rich Internet Applications for customer-facing websites Establish the Laszlo platform as the standard, open source software platform of choice for such applications Laszlo Systems, Inc. 5
Slide 6: Demos Calendar Dashboard Laszlo Systems, Inc. 6
Slide 7: Who Uses OpenLaszlo? Over 20M consumers have used Laszlo-based applications 7 Laszlo Systems, Inc.
Slide 8: Under the Hood: Platform Architecture XML Source OpenLaszlo Platform Files swf object file Compiler Linker Flash player GIFs, JPEGs, User interface Runtime PNGs components Library J2EE Server Client Laszlo Systems, Inc. 8
Slide 9: Under the Hood (2): Removing the Server XML Source OpenLaszlo Platform Files swf object file Compiler Linker Web Server Flash player GIFs, JPEGs, User interface Runtime PNGs components Library Client Laszlo Systems, Inc. 9
Slide 10: Script Compiler Compiles JavaScript to Flash bytecode Plus unanticipated cool features Laszlo Systems, Inc. 10
Slide 11: Laszlo Source Code (LZX) <canvas> <window> <button onclick=” animate(‘x’, 100, 1000, true)”> Click me! </button> </window> </canvas> Source hierarchy mirrors object hierarchy Embedded JavaScript Constraints, data binding, and declarative states Laszlo Systems, Inc. 11
Slide 12: Script Compiler Requirements 100% Java JavaScript -> ActionScript byte code Three months (concurrent with language design, API design, XML compiler, and compiler architecture) Why not Java? I’d written a lot of code in Java and Python, and didn’t think I could write the Java version in time. JWordNet PyWordNet Evaluation Java Jython SML ICON Laszlo Systems, Inc. 12
Slide 13: Script Compiler: The 10,000 foot view LZX swf (Flash) Source File object file OpenLaszlo Compiler 88450008006174747273006e61 6d65004c7a496e7374616e74696 174655669657700436c69636b2 06d6521006368696c6472656e0 <window> 077696e646f7700627574746f6e 007465787400960c0007020000 <button>Click me!</button> 000800070000000043960d0008 04080008070803070100000043 </window> 96090008010806070200000043 96050007010000004296090008 01080507030000004396070007 0200000008023d1700 Laszlo Systems, Inc. 13
Slide 14: Script Compiler: The 5,000 foot view LZX swf (Flash) Source File object file XML Linker Compiler Script Compiler JavaScript ActionScript byte code Laszlo Systems, Inc. 14
Slide 15: Script Compiler: The 1,000 foot view LZX swf (Flash) Source File object file XML Java Linker Compiler ActionScript JavaScript byte code JavaCC Jython Parser Assembler Code Generator JavaScript ActionScript AST assembly Laszlo Systems, Inc. 15
Slide 16: Compilation Stages LZX (XML) ActionScript assembly Byte code constants 'attrs' 'name' 88450008006 <window> 17474727300 'LzInstantiateView' 6e616d65004c 'Click me!' 'children' <button>Click me!</button> 7a496e737461 'window' 'button' 'text' 6e746961746 </window> push '2' 'attrs' '0' 55669657700 436c69636b2 initObject 06d65210063 push 'children' 'attrs' 68696c64726 'text' 'Click me!' '1' 56e0077696e6 46f770062757 initObject 4746f6e00746 push 'name' 'button' '2' 5787400960c JavaScript 00070200000 initObject LzInstantiateView( 00800070000 push '1' 000043960d0 {name: \"window\", 00804080008 initArray 07080307010 attrs: {}, push 'name' 'window' '3' 00000439609 children: 00080108060 initObject 70200000043 [{name: \"button\", push '2' 96050007010 attrs: {text: \"Click 00000429609 'LzInstantiateView' 00080108050 me!\"}}]}, callFunction 70300000043 2); 96070007020 pop 0000008023d 1700 Laszlo Systems, Inc. 16
Slide 17: Embedded JavaScript <button onclick=\"animate('x', 100, 1000, true)\"/> LzInstantiateView( {name: \"button\", attrs: { $events: {onclick: function $test$2Elzx_2_52_onclick_event () { animate('x', 100, 1000, true)}}, clickable: true}}, 1); Laszlo Systems, Inc. 17
Slide 18: Results Three months 4.5K LOC (3K Jython, 1.5K Java + JavaCC) 25 bugs over three years Laszlo Systems, Inc. 18
Slide 19: Jython Advantages REPL Literal syntax Doctest Reflection Java integration Laszlo Systems, Inc. 19
Slide 20: REPL >>> c('a=b') constants 'a' 'b' push 'a' 'b' getVariable setVariable >>> c('a=a*2') constants 'a' push 'a' 'a' getVariable push '2' multiply setVariable >>> c('function f(a,b) {return a+b}') function2 f(r:2='a', r:1='b') () push 'r:2' 'r:1' add return end Laszlo Systems, Inc. 20
Slide 21: Doctest def substitute(self, str, **keys): \"\"\"Parse an expression and replace any identifier with the same name as a keyword argument to this function, with the value of that key. If the value has type Splice, it's spliced into place instead of substituting at the same level. >>> s = Parser().substitute >>> s('[0,1,2]') (ASTArrayLiteral, Literal(0.0), Literal(1), Literal(2)) >>> s('[_0,1,2]', _0=Literal(\"sub\")) (ASTArrayLiteral, Literal(sub), Literal(1), Literal(2)) >>> s('[_0,1,2]', _0=s('[a,b,c]')) (ASTArrayLiteral, (ASTArrayLiteral, ASTIdentifier(a), ASTIdentifier(b), ASTIdentifier(c)), Literal(1), Literal(2)) >>> s('[_0,1,2]', _0=Splice(s('[a,b,c]'))) (ASTArrayLiteral, ASTArrayLiteral, ASTIdentifier(a), ASTIdentifier(b), ASTIdentifier(c), Literal(1), Literal(2)) N.B., there is no attempt to enforce macro hygiene \"\"\" Laszlo Systems, Inc. 21
Slide 22: Concise Literal Syntax DefineTests( 'label', Stmts(['a: while (f()) b: while (g()) {break; h()}', 'a: while (f()) b: while (g()) {break b; h()}', 'a: while (f()) b: while (g()) {break a; h()}', 'a: while (f()) b: for (p in obj) {break; h()}', 'a: while (f()) b: for (p in obj) {break b; h()}', 'a: while (f()) b: for (p in obj) {break a; h()}', 'a: for (p in obj) b: while (g()) {break; h()}', 'a: for (p in obj) b: while (g()) {break b; h()}', 'a: for (p in obj) b: while (g()) {break a; h()}', 'a: for (p in obj) b: for (p in obj) {break; h()}', 'a: for (p in obj) b: for (p in obj) {break b; h()}', 'a: for (p in obj) b: for (p in obj) {break a; h()}', ])) Laszlo Systems, Inc. 22
Slide 23: Reflection def visit(self, node): fn = getattr(self, 'visit' + node.name) fn(node, *node.children) def visitArrayLiteral(self, node, *args): ... def visitBinaryExpressionSequence(self, node, a, op, *args): ... def visitFunctionDeclaration(self, node, *args): ... def visitIdentifier(self, node): ... def visitLiteral(self, node): ... Laszlo Systems, Inc. 23
Slide 24: Jython disadvantages Execution speed Deployment issues Laszlo Systems, Inc. 24
Slide 25: Port Assembler to Java 1.2KLoC Jython -> 2.7KLoC Java Harder to work with But...10 times as fast Laszlo Systems, Inc. 25
Slide 26: Deployment Issues Deploying Jython within a J2EE Servlet has (had?) severe class loader issues Jython triggered a memory manager error in JVM 1.4 Jython 2.0/Java 1.5 issues Laszlo Systems, Inc. 26
Slide 27: However... Xalan, Xerces, Jing, Commons Logging, and JDOM all had issues too Laszlo Systems, Inc. 27
Slide 28: The First Pattern Jython saved us a lot of time during development, but cost (less) time during deployment. But so did several other Java libraries But this still makes it difficult to justify, especially to deployers (who don’t see the development-time advantages) Laszlo Systems, Inc. 28
Slide 29: And then we were done... Laszlo Systems, Inc. 29
Slide 30: Constraint System (Laszlo 1.0) Requirements • Width of view is a function of parent’s width and view’s ‘border’ property • Width is updated whenever parent’s width changes • Width is updated whenever ‘border’ property value changes Observer Pattern <view> <method event=”oninit”> registerListener(parent, ‘width’, myWidthListener); registerListener(this, ‘border’, myWidthListener); myWidthListener(); </method> <method name=”myWidthListener”> this.width = parent.width - 2*this.border; </method> </view> Constraint expression <view width=”${parent.width - 2*this.border}”/> Laszlo Systems, Inc. 30
Slide 31: Constraint Implementation <view width=\"${parent.width - 2*this.border}\"/> LzInstantiateView( {attrs: { name: \"view\", $refs: { width: function $test$2Elzx_2_46_width_always () { this.setAttribute(\"width\", parent.width - 2*this.border)}}}}, 1); + $test$2Elzx_2_46_width_always.dependencies = [parent, ‘width’, this, ‘border’] Laszlo Systems, Inc. 31
Slide 32: And then we were done... Laszlo Systems, Inc. 32
Slide 33: KRANK Feature (Laszlo 2.0) Problem: Slow initialization time Solution: Initialize the application prior to deployment Results: 2-4x performance increase, at expense of developer time and application size Laszlo Systems, Inc. 33
Slide 34: KRANK feature LZX Instrumented Source File object file OpenLaszlo Compiler Flash player KRANK Compiler Serialized Optimized application object file state Laszlo Systems, Inc. 34
Slide 35: But now we’re really done.. Laszlo Systems, Inc. 35
Slide 36: The Second Pattern Python (Jython) is good for prototyping But, you don’t know when you’re done prototyping Laszlo Systems, Inc. 36
Slide 37: OpenLaszlo Doc Tools Laszlo Systems, Inc. 37
Slide 38: OpenLaszlo Doc Tools schema/ schema/ lzx.rng rngparse.xml ant targets imports schema/ components/ schema/ tagdocs/ tag-xml Document **/*.lzx Document rng2xml.py *.xml server/jsdocs/ server/sc/ lfc/**/*.as api-xml Document Document *.xml jsdoc2xml.py server/sc/ copy xmldocutils.py docs/src/** build/ wrappers/**/ reference/ makeXML.py Document *xml Document xml/*.xml combined-xml wrappers/ Document *.html build/ reference/ raw-html makeHTML.py Document html/*.html LPS/docs/ reference/ xsl/format.xsl Document reference-html *.html Laszlo Systems, Inc. 38
Slide 39: Lots of Languages: Developers Guide LZX XHTML Target Languages JavaScript RELAX NG XML Definition Languages Implementation JavaCC Java Jython Python XSLT Languages Laszlo Systems, Inc. 39
Slide 40: Lots of Languages: LZX Reference LZX XHTML Target Languages JavaScript RELAX NG XML Definition Languages Implementation JavaCC Java Jython Python XSLT Languages Utility Library Laszlo Systems, Inc. 40
Slide 41: The Third Pattern There are different requirements for build system and deployment Components may move between build system and deployment... ...or be shared by both Laszlo Systems, Inc. 41
Slide 42: Conclusions Laszlo Systems, Inc. 42
Slide 43: Experimentation Let us experiment with new features: Krank Constraints PUSH merge Macros Swings of “I wish we had ported” vs. “I’m glad we didn’t port yet” Don’t know when you’re done prototyping Laszlo Systems, Inc. 43
Slide 44: Lots of Languages (2) LZX XHTML Target Languages JavaScript RELAX NG XML Definition Languages Implementation JavaCC Java Jython Python XSLT Languages Process Implement Interoperate Laszlo Systems, Inc. 44
Slide 45: Migration Smooth path between Python and Jython Possible path between Jython and Java Excellent integration between Jython and Java-based tools Laszlo Systems, Inc. 45
Slide 46: What would help Jython? Smoother path to performance Smoother path to deployment Laszlo Systems, Inc. 46
Slide 47: Q&A Laszlo Systems, Inc. 47



Add a comment on Slide 1
If you have a SlideShare account, login to comment; else you can comment as a guest- Favorites & Groups
Showing 1-50 of 2 (more)