SlideShare a Scribd company logo
1 of 30
Download to read offline
The Parenscript Common Lisp to JavaScript
                 compiler

  Vladimir Sedach <vsedach@gmail.com>
What Parenscript is not

   Not a full ANSI INCITS 226-1994 (the standard
    formerly known as X3J13) implementation in
    JavaScript
   Not a Lisp interpreter in JavaScript
   Not a framework, toolkit, UI or AJAX library
What Parenscript doesn't do

   No dependencies or run-time library
       Any JS code produced runs as-is
   No new data types
   No weird calling convention
       Any PS code can call any JS code directly and vice-
        versa
   No whole program compilation
       JS code can be produced incrementally
Where is Parenscript used?

   Web frameworks: BKNR, UCW, TPD2,
    Weblocks
   Libraries: cl-closure-template, Suave, css-lite,
    clouchdb, uri-template
   Many startups and commercial projects
Parenscript history

   March 2005, Manuel Odendahl announces
    initial release
   Swallowed up by the bese project in 2006
   Skysheet developers spin Parenscript out as
    separate project again in 2007, take over
    development, do lots of PR
Similar projects

   Not many options for Common Lisp:
       Jason Kantz's JSGEN (2006, s-exp over JS)
       Peter Seibel's Lispscript (2006?, s-exp over JS)
   Many more options for Scheme:
       Scheme2JS (2005?)
       Feeley and Gaudron's JSS
       Many others
   Moritz Heidkamp's survey of Lisp-in-JavaScript
    implementations lists 28!
Use cases

   Lisp at runtime
   No Lisp at runtime
Lisp at runtime

   Compile to inline JavaScript in HTML page
   Stream client-specific JavaScript to browser via
    XMLHttpRequest or page loads
   SWANK-based development environment
No Lisp at runtime

   Compile to static files sent to browser
       If done with a runtime, can use all of CL features for
        a build/deploy/cache system
   Compile to library to be used by other JS code
   Compile to JS client- and server-side (node.js)
    code at the same time
       Deploy JS only
       Parenscript used as static compiler for whole web
        stack
Implementation Techniques
What should JS code look like?

   Write CL, but debug JS
   Generated code has to be short, readable,
    idiomatic
   ”Optimization” in the context of this talk means
    ”more readable code”
   What about performance?
       Can only assume that JS compilers try to optimize
        for code written by humans (ie – readable and
        idiomatic code)
Statements vs Expressions

   In JavaScript, can transform any statement to
    an expression by wrapping it in a lambda
       Except for BREAK, CONTINUE, and RETURN
   Many optimizations to avoid lambda-wrapping
    possible, depending on combination of special
    forms
Function argument lists

   Full Common Lisp lambda lists in JavaScript
       In a way completely compatible with other
        JavaScript code
   ARGUMENTS is great
   NULL (argument provided) vs UNDEFINED
    (argument not provided)
   Keywords: f(”key2”, value2, ”key1”, value1);
       CL keywords and JS strings both self-evaluating
Macros

   Share the same representation (macro-
    function) in CL and PS compilers
   But have different namespaces
   Share same code between client (CL) and
    server (JS) even if implementation details
    completely different (ex – IO, graphics)
       Without modifying CL code
       PS macros can shadow CL functions
Data structures

   No car/cdr
   Many Common Lisp forms are sequence
    oriented (DOLIST, LOOP, etc.)
   Most idiomatic Common Lisp code uses these
    forms
   Most code turns out to care about sequences,
    not linked lists vs arrays, and works as-is with
    JS arrays
Namespace (Lisp-1 and Lisp-N)

   JavaScript is a Lisp-1
   Common Lisp is a Lisp-4
       With macros, Lisp-N
   Parenscript tries to be a Lisp-2 (separate
    variable and function namespaces)
   Code can be output unambiguously for lexically
    bound names (via α-renaming), but free
    variables referring to globals might cause
    conflicts
   No thought given to hygiene
Namespace (package system)

   All Parenscript symbols are CL symbols
   Packages can be given prefixes to namespace
    in JS:
       foo::bar => foo_bar
   Package system also used for obfuscation
    and/or minification
   Exports list used to produce JS libraries with
    minified internals and prefixed API names
Namespace (case and escape)

   CL readtable case-insensitive by default, but
    can be set to preserve case
   Parenscript recognizes mixed-case symbols
    and outputs them correctly
   Simple translation for case-insensitive ones:
       foo-bar => fooBar
   JS reserved chars escaped:
       foo* => foostar
JavaScript dot operator

   Causes confusion
       Some people think it's ok to use it for namespacing
   foo.bar is really (getprop foo 'bar)
   What about foo.bar.baz(foobar)?
       (funcall (getprop (getprop foo 'bar) 'baz) foobar)
   Macros to the rescue:
       (funcall (@ foo bar baz) foobar)
JavaScript dot operator 2

   Why not (foo.bar.baz foobar)?
   Parenscript 1 did it in compilation step
       Turns out this doesn't work well with package
        system, breaks symbol macros
       Symbol macros used for a lot of things in
        Parenscript 2 compiler
   Possible to do it in the reader
       But ”.” is already reserved for dotted lists
       Dotted lists are evil; remove them from Lisp
Lexical scoping
   Done by using α-renaming to declare variables
    in nearest function scope:
      (lambda ()                function () {
       (let ((x 1))                 var x = 1;
        (let ((x 2))                var x1 = 2;
          x)))                      return x1;
                                }
Lexical scoping: loops

   For variables in loops, JS creates a shared
    binding for all iterations, breaking closures
   WITH trick from Scheme2JS:
      (dotimes (i 10)         for (var i = 0; i < 10; i += 1) {
       (lambda () (+ i 1)))    with ({i : i}) {
                                 function () {
                                       return i + 1;
                              };};};
Dynamic scoping

   TRY/FINALLY to set a global variable
    (let ((*foo* 1))   var FOO_TMPSTACK7;
      (+ *foo* 2))     try {
                           FOO_TMPSTACK7 = FOO;
                           FOO = 1;
                           return FOO + 2;
                       }
                       finally {
                         FOO = FOO_TMPSTACK7;
                       };
Multiple value return

   ARGUMENTS has 'callee' property (function)
   'callee' has 'caller' property (function)
   Functions are JS objects, can attach arbitrary
    properties to them
   To return MV:
       arguments.callee.caller.mv = [val2, ...]
   To receive MV:
       others_vals = arguments.callee.mv
Multiple value return 2

   Actually requires more cleanup code than this.
   arguments.callee works even when calling
    to/from functions that don't know about
    Parenscript (a global ”return value arg”
    wouldn't)
   Non-lexical returns (see next slide) with multiple
    values easier to implement (but aren't yet)
Control transfer

   JavaScript only supports RETURNing from
    innermost function, BREAKing out of innermost
    block or loop
   Can implement CL's BLOCK/RETURN-FROM
    and CATCH/THROW using TRY-CATCH-
    FINALLY in general case
   Optimizations possible depending on special
    forms, whether a return value is wanted
Tools and future developments
CLOS

   Red Daly's PSOS library provides CLOS and
    Common Lisp's condition and resumable
    exception system
       Not part of core Parenscript because it requires run-
        time library and introduces new types
   Possible to build up a full Common Lisp in
    JavaScript this way using Parenscript as a
    cross-compiler
Development environments

   SWANK-based
       slime-proxy
   Non-SWANK
       Numen (V8 only, to be released)
Future directions

   JS implementations have mostly caught on
    speed-wise
       But have not, and most likely will not, catch up in
        efficient memory consumption
   Would like a full Common Lisp implementation
    in JS on the server (V8, Rhino, etc.) and web
    browser (Firefox, Chrome, etc.)

More Related Content

What's hot

J Ruby Whirlwind Tour
J Ruby Whirlwind TourJ Ruby Whirlwind Tour
J Ruby Whirlwind Tour
oscon2007
 
tDiary annual report 2009 - Sapporo Ruby Kaigi02
tDiary annual report 2009 - Sapporo Ruby Kaigi02tDiary annual report 2009 - Sapporo Ruby Kaigi02
tDiary annual report 2009 - Sapporo Ruby Kaigi02
Hiroshi SHIBATA
 
Ruby projects of interest for DevOps
Ruby projects of interest for DevOpsRuby projects of interest for DevOps
Ruby projects of interest for DevOps
Ricardo Sanchez
 

What's hot (20)

J Ruby Whirlwind Tour
J Ruby Whirlwind TourJ Ruby Whirlwind Tour
J Ruby Whirlwind Tour
 
Golang Performance : microbenchmarks, profilers, and a war story
Golang Performance : microbenchmarks, profilers, and a war storyGolang Performance : microbenchmarks, profilers, and a war story
Golang Performance : microbenchmarks, profilers, and a war story
 
Deploying Perl apps on dotCloud
Deploying Perl apps on dotCloudDeploying Perl apps on dotCloud
Deploying Perl apps on dotCloud
 
Why scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with thisWhy scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with this
 
Large-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 MinutesLarge-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 Minutes
 
Devel::NYTProf v3 - 200908 (OUTDATED, see 201008)
Devel::NYTProf v3 - 200908 (OUTDATED, see 201008)Devel::NYTProf v3 - 200908 (OUTDATED, see 201008)
Devel::NYTProf v3 - 200908 (OUTDATED, see 201008)
 
JRuby with Java Code in Data Processing World
JRuby with Java Code in Data Processing WorldJRuby with Java Code in Data Processing World
JRuby with Java Code in Data Processing World
 
Os Harkins
Os HarkinsOs Harkins
Os Harkins
 
Fluentd v0.14 Plugin API Details
Fluentd v0.14 Plugin API DetailsFluentd v0.14 Plugin API Details
Fluentd v0.14 Plugin API Details
 
The art of concurrent programming
The art of concurrent programmingThe art of concurrent programming
The art of concurrent programming
 
Node.js System: The Approach
Node.js System: The ApproachNode.js System: The Approach
Node.js System: The Approach
 
tDiary annual report 2009 - Sapporo Ruby Kaigi02
tDiary annual report 2009 - Sapporo Ruby Kaigi02tDiary annual report 2009 - Sapporo Ruby Kaigi02
tDiary annual report 2009 - Sapporo Ruby Kaigi02
 
CPAN Training
CPAN TrainingCPAN Training
CPAN Training
 
Javascript asynchronous
Javascript asynchronousJavascript asynchronous
Javascript asynchronous
 
Getting started with Perl XS and Inline::C
Getting started with Perl XS and Inline::CGetting started with Perl XS and Inline::C
Getting started with Perl XS and Inline::C
 
An introduction and future of Ruby coverage library
An introduction and future of Ruby coverage libraryAn introduction and future of Ruby coverage library
An introduction and future of Ruby coverage library
 
Ruby projects of interest for DevOps
Ruby projects of interest for DevOpsRuby projects of interest for DevOps
Ruby projects of interest for DevOps
 
Javantura v3 - ES6 – Future Is Now – Nenad Pečanac
Javantura v3 - ES6 – Future Is Now – Nenad PečanacJavantura v3 - ES6 – Future Is Now – Nenad Pečanac
Javantura v3 - ES6 – Future Is Now – Nenad Pečanac
 
Andres Gutierrez "Phalcon 3.0, Zephir & PHP7"
Andres Gutierrez "Phalcon 3.0, Zephir & PHP7"Andres Gutierrez "Phalcon 3.0, Zephir & PHP7"
Andres Gutierrez "Phalcon 3.0, Zephir & PHP7"
 
Mongo db - How we use Go and MongoDB by Sam Helman
Mongo db - How we use Go and MongoDB by Sam HelmanMongo db - How we use Go and MongoDB by Sam Helman
Mongo db - How we use Go and MongoDB by Sam Helman
 

Similar to The Parenscript Common Lisp to JavaScript compiler

LD_PRELOAD Exploitation - DC9723
LD_PRELOAD Exploitation - DC9723LD_PRELOAD Exploitation - DC9723
LD_PRELOAD Exploitation - DC9723
Iftach Ian Amit
 
Clojure and The Robot Apocalypse
Clojure and The Robot ApocalypseClojure and The Robot Apocalypse
Clojure and The Robot Apocalypse
elliando dias
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLs
intelliyole
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
David Padbury
 

Similar to The Parenscript Common Lisp to JavaScript compiler (20)

ES6 - JavaCro 2016
ES6 - JavaCro 2016ES6 - JavaCro 2016
ES6 - JavaCro 2016
 
LD_PRELOAD Exploitation - DC9723
LD_PRELOAD Exploitation - DC9723LD_PRELOAD Exploitation - DC9723
LD_PRELOAD Exploitation - DC9723
 
Clojure and The Robot Apocalypse
Clojure and The Robot ApocalypseClojure and The Robot Apocalypse
Clojure and The Robot Apocalypse
 
Exciting JavaScript - Part II
Exciting JavaScript - Part IIExciting JavaScript - Part II
Exciting JavaScript - Part II
 
Angular JS in 2017
Angular JS in 2017Angular JS in 2017
Angular JS in 2017
 
Specialized Compiler for Hash Cracking
Specialized Compiler for Hash CrackingSpecialized Compiler for Hash Cracking
Specialized Compiler for Hash Cracking
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLs
 
Panama.pdf
Panama.pdfPanama.pdf
Panama.pdf
 
Modern JS with ES6
Modern JS with ES6Modern JS with ES6
Modern JS with ES6
 
Evolving js
Evolving jsEvolving js
Evolving js
 
SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra
SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra  SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra
SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra
 
Sugar Presentation - YULHackers March 2009
Sugar Presentation - YULHackers March 2009Sugar Presentation - YULHackers March 2009
Sugar Presentation - YULHackers March 2009
 
Ruby on Rails Training - Module 1
Ruby on Rails Training - Module 1Ruby on Rails Training - Module 1
Ruby on Rails Training - Module 1
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Preparing for Scala 3
Preparing for Scala 3Preparing for Scala 3
Preparing for Scala 3
 
whats new in java 8
whats new in java 8 whats new in java 8
whats new in java 8
 
Java 8 Overview
Java 8 OverviewJava 8 Overview
Java 8 Overview
 
Common Node
Common NodeCommon Node
Common Node
 
Java 7 - New Features - by Mihail Stoynov and Svetlin Nakov
Java 7 - New Features - by Mihail Stoynov and Svetlin NakovJava 7 - New Features - by Mihail Stoynov and Svetlin Nakov
Java 7 - New Features - by Mihail Stoynov and Svetlin Nakov
 
Scala+data
Scala+dataScala+data
Scala+data
 

Recently uploaded

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Recently uploaded (20)

Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 

The Parenscript Common Lisp to JavaScript compiler

  • 1. The Parenscript Common Lisp to JavaScript compiler Vladimir Sedach <vsedach@gmail.com>
  • 2. What Parenscript is not  Not a full ANSI INCITS 226-1994 (the standard formerly known as X3J13) implementation in JavaScript  Not a Lisp interpreter in JavaScript  Not a framework, toolkit, UI or AJAX library
  • 3. What Parenscript doesn't do  No dependencies or run-time library  Any JS code produced runs as-is  No new data types  No weird calling convention  Any PS code can call any JS code directly and vice- versa  No whole program compilation  JS code can be produced incrementally
  • 4. Where is Parenscript used?  Web frameworks: BKNR, UCW, TPD2, Weblocks  Libraries: cl-closure-template, Suave, css-lite, clouchdb, uri-template  Many startups and commercial projects
  • 5. Parenscript history  March 2005, Manuel Odendahl announces initial release  Swallowed up by the bese project in 2006  Skysheet developers spin Parenscript out as separate project again in 2007, take over development, do lots of PR
  • 6. Similar projects  Not many options for Common Lisp:  Jason Kantz's JSGEN (2006, s-exp over JS)  Peter Seibel's Lispscript (2006?, s-exp over JS)  Many more options for Scheme:  Scheme2JS (2005?)  Feeley and Gaudron's JSS  Many others  Moritz Heidkamp's survey of Lisp-in-JavaScript implementations lists 28!
  • 7. Use cases  Lisp at runtime  No Lisp at runtime
  • 8. Lisp at runtime  Compile to inline JavaScript in HTML page  Stream client-specific JavaScript to browser via XMLHttpRequest or page loads  SWANK-based development environment
  • 9. No Lisp at runtime  Compile to static files sent to browser  If done with a runtime, can use all of CL features for a build/deploy/cache system  Compile to library to be used by other JS code  Compile to JS client- and server-side (node.js) code at the same time  Deploy JS only  Parenscript used as static compiler for whole web stack
  • 11. What should JS code look like?  Write CL, but debug JS  Generated code has to be short, readable, idiomatic  ”Optimization” in the context of this talk means ”more readable code”  What about performance?  Can only assume that JS compilers try to optimize for code written by humans (ie – readable and idiomatic code)
  • 12. Statements vs Expressions  In JavaScript, can transform any statement to an expression by wrapping it in a lambda  Except for BREAK, CONTINUE, and RETURN  Many optimizations to avoid lambda-wrapping possible, depending on combination of special forms
  • 13. Function argument lists  Full Common Lisp lambda lists in JavaScript  In a way completely compatible with other JavaScript code  ARGUMENTS is great  NULL (argument provided) vs UNDEFINED (argument not provided)  Keywords: f(”key2”, value2, ”key1”, value1);  CL keywords and JS strings both self-evaluating
  • 14. Macros  Share the same representation (macro- function) in CL and PS compilers  But have different namespaces  Share same code between client (CL) and server (JS) even if implementation details completely different (ex – IO, graphics)  Without modifying CL code  PS macros can shadow CL functions
  • 15. Data structures  No car/cdr  Many Common Lisp forms are sequence oriented (DOLIST, LOOP, etc.)  Most idiomatic Common Lisp code uses these forms  Most code turns out to care about sequences, not linked lists vs arrays, and works as-is with JS arrays
  • 16. Namespace (Lisp-1 and Lisp-N)  JavaScript is a Lisp-1  Common Lisp is a Lisp-4  With macros, Lisp-N  Parenscript tries to be a Lisp-2 (separate variable and function namespaces)  Code can be output unambiguously for lexically bound names (via α-renaming), but free variables referring to globals might cause conflicts  No thought given to hygiene
  • 17. Namespace (package system)  All Parenscript symbols are CL symbols  Packages can be given prefixes to namespace in JS:  foo::bar => foo_bar  Package system also used for obfuscation and/or minification  Exports list used to produce JS libraries with minified internals and prefixed API names
  • 18. Namespace (case and escape)  CL readtable case-insensitive by default, but can be set to preserve case  Parenscript recognizes mixed-case symbols and outputs them correctly  Simple translation for case-insensitive ones:  foo-bar => fooBar  JS reserved chars escaped:  foo* => foostar
  • 19. JavaScript dot operator  Causes confusion  Some people think it's ok to use it for namespacing  foo.bar is really (getprop foo 'bar)  What about foo.bar.baz(foobar)?  (funcall (getprop (getprop foo 'bar) 'baz) foobar)  Macros to the rescue:  (funcall (@ foo bar baz) foobar)
  • 20. JavaScript dot operator 2  Why not (foo.bar.baz foobar)?  Parenscript 1 did it in compilation step  Turns out this doesn't work well with package system, breaks symbol macros  Symbol macros used for a lot of things in Parenscript 2 compiler  Possible to do it in the reader  But ”.” is already reserved for dotted lists  Dotted lists are evil; remove them from Lisp
  • 21. Lexical scoping  Done by using α-renaming to declare variables in nearest function scope: (lambda () function () { (let ((x 1)) var x = 1; (let ((x 2)) var x1 = 2; x))) return x1; }
  • 22. Lexical scoping: loops  For variables in loops, JS creates a shared binding for all iterations, breaking closures  WITH trick from Scheme2JS: (dotimes (i 10) for (var i = 0; i < 10; i += 1) { (lambda () (+ i 1))) with ({i : i}) { function () { return i + 1; };};};
  • 23. Dynamic scoping  TRY/FINALLY to set a global variable (let ((*foo* 1)) var FOO_TMPSTACK7; (+ *foo* 2)) try { FOO_TMPSTACK7 = FOO; FOO = 1; return FOO + 2; } finally { FOO = FOO_TMPSTACK7; };
  • 24. Multiple value return  ARGUMENTS has 'callee' property (function)  'callee' has 'caller' property (function)  Functions are JS objects, can attach arbitrary properties to them  To return MV:  arguments.callee.caller.mv = [val2, ...]  To receive MV:  others_vals = arguments.callee.mv
  • 25. Multiple value return 2  Actually requires more cleanup code than this.  arguments.callee works even when calling to/from functions that don't know about Parenscript (a global ”return value arg” wouldn't)  Non-lexical returns (see next slide) with multiple values easier to implement (but aren't yet)
  • 26. Control transfer  JavaScript only supports RETURNing from innermost function, BREAKing out of innermost block or loop  Can implement CL's BLOCK/RETURN-FROM and CATCH/THROW using TRY-CATCH- FINALLY in general case  Optimizations possible depending on special forms, whether a return value is wanted
  • 27. Tools and future developments
  • 28. CLOS  Red Daly's PSOS library provides CLOS and Common Lisp's condition and resumable exception system  Not part of core Parenscript because it requires run- time library and introduces new types  Possible to build up a full Common Lisp in JavaScript this way using Parenscript as a cross-compiler
  • 29. Development environments  SWANK-based  slime-proxy  Non-SWANK  Numen (V8 only, to be released)
  • 30. Future directions  JS implementations have mostly caught on speed-wise  But have not, and most likely will not, catch up in efficient memory consumption  Would like a full Common Lisp implementation in JS on the server (V8, Rhino, etc.) and web browser (Firefox, Chrome, etc.)