SlideShare a Scribd company logo
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 (20)

J Ruby Whirlwind Tour
J Ruby Whirlwind Tour
oscon2007
 
Golang Performance : microbenchmarks, profilers, and a war story
Golang Performance : microbenchmarks, profilers, and a war story
Aerospike
 
Deploying Perl apps on dotCloud
Deploying Perl apps on dotCloud
daoswald
 
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 this
Ruslan Shevchenko
 
Large-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 Minutes
Hiroshi SHIBATA
 
Devel::NYTProf v3 - 200908 (OUTDATED, see 201008)
Devel::NYTProf v3 - 200908 (OUTDATED, see 201008)
Tim Bunce
 
JRuby with Java Code in Data Processing World
JRuby with Java Code in Data Processing World
SATOSHI TAGOMORI
 
Os Harkins
Os Harkins
oscon2007
 
Fluentd v0.14 Plugin API Details
Fluentd v0.14 Plugin API Details
SATOSHI TAGOMORI
 
The art of concurrent programming
The art of concurrent programming
Iskren Chernev
 
Node.js System: The Approach
Node.js System: The Approach
Haci Murat Yaman
 
tDiary annual report 2009 - Sapporo Ruby Kaigi02
tDiary annual report 2009 - Sapporo Ruby Kaigi02
Hiroshi SHIBATA
 
CPAN Training
CPAN Training
Pedro Figueiredo
 
Javascript asynchronous
Javascript asynchronous
kang taehun
 
Getting started with Perl XS and Inline::C
Getting started with Perl XS and Inline::C
daoswald
 
An introduction and future of Ruby coverage library
An introduction and future of Ruby coverage library
mametter
 
Ruby projects of interest for DevOps
Ruby projects of interest for DevOps
Ricardo Sanchez
 
Javantura v3 - ES6 – Future Is Now – Nenad Pečanac
Javantura v3 - ES6 – Future Is Now – Nenad Pečanac
HUJAK - Hrvatska udruga Java korisnika / Croatian Java User Association
 
Andres Gutierrez "Phalcon 3.0, Zephir & PHP7"
Andres Gutierrez "Phalcon 3.0, Zephir & PHP7"
Fwdays
 
Mongo db - How we use Go and MongoDB by Sam Helman
Mongo db - How we use Go and MongoDB by Sam Helman
Hakka Labs
 
J Ruby Whirlwind Tour
J Ruby Whirlwind Tour
oscon2007
 
Golang Performance : microbenchmarks, profilers, and a war story
Golang Performance : microbenchmarks, profilers, and a war story
Aerospike
 
Deploying Perl apps on dotCloud
Deploying Perl apps on dotCloud
daoswald
 
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 this
Ruslan Shevchenko
 
Large-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 Minutes
Hiroshi SHIBATA
 
Devel::NYTProf v3 - 200908 (OUTDATED, see 201008)
Devel::NYTProf v3 - 200908 (OUTDATED, see 201008)
Tim Bunce
 
JRuby with Java Code in Data Processing World
JRuby with Java Code in Data Processing World
SATOSHI TAGOMORI
 
Fluentd v0.14 Plugin API Details
Fluentd v0.14 Plugin API Details
SATOSHI TAGOMORI
 
The art of concurrent programming
The art of concurrent programming
Iskren Chernev
 
Node.js System: The Approach
Node.js System: The Approach
Haci Murat Yaman
 
tDiary annual report 2009 - Sapporo Ruby Kaigi02
tDiary annual report 2009 - Sapporo Ruby Kaigi02
Hiroshi SHIBATA
 
Javascript asynchronous
Javascript asynchronous
kang taehun
 
Getting started with Perl XS and Inline::C
Getting started with Perl XS and Inline::C
daoswald
 
An introduction and future of Ruby coverage library
An introduction and future of Ruby coverage library
mametter
 
Ruby projects of interest for DevOps
Ruby projects of interest for DevOps
Ricardo Sanchez
 
Andres Gutierrez "Phalcon 3.0, Zephir & PHP7"
Andres Gutierrez "Phalcon 3.0, Zephir & PHP7"
Fwdays
 
Mongo db - How we use Go and MongoDB by Sam Helman
Mongo db - How we use Go and MongoDB by Sam Helman
Hakka Labs
 

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

Evolving js
Evolving js
shavien
 
DEVCON1 - BooJs
DEVCON1 - BooJs
Iván Montes
 
Javascript The Good Parts v2
Javascript The Good Parts v2
Federico Galassi
 
intro.ppt
intro.ppt
Luis Soza
 
Lisp, An Introduction.ppt
Lisp, An Introduction.ppt
Luis Soza
 
intro.ppt
intro.ppt
AishwaryaKulal1
 
Javascript as a Platform
Javascript as a Platform
Vlad Mysla
 
Exciting JavaScript - Part II
Exciting JavaScript - Part II
Eugene Lazutkin
 
Javascript The Good Parts
Javascript The Good Parts
Federico Galassi
 
ES6 - JavaCro 2016
ES6 - JavaCro 2016
Nenad Pecanac
 
A closure ekon16
A closure ekon16
Max Kleiner
 
Exciting JavaScript - Part I
Exciting JavaScript - Part I
Eugene Lazutkin
 
Clojurescript slides
Clojurescript slides
elliando dias
 
A Re-Introduction to JavaScript
A Re-Introduction to JavaScript
Simon Willison
 
Smalltalk, the dynamic language
Smalltalk, the dynamic language
mohamedsamyali
 
I know Java, why should I consider Clojure?
I know Java, why should I consider Clojure?
sbjug
 
ClojureScript Anatomy
ClojureScript Anatomy
Mike Fogus
 
Introduction to JavaScript for Modern Software Development
Introduction to JavaScript for Modern Software Development
Kenneth Geisshirt
 
JavaScriptとLisp
JavaScriptとLisp
taiju higashi
 
JS - Basics
JS - Basics
John Fischer
 
Evolving js
Evolving js
shavien
 
Javascript The Good Parts v2
Javascript The Good Parts v2
Federico Galassi
 
Lisp, An Introduction.ppt
Lisp, An Introduction.ppt
Luis Soza
 
Javascript as a Platform
Javascript as a Platform
Vlad Mysla
 
Exciting JavaScript - Part II
Exciting JavaScript - Part II
Eugene Lazutkin
 
A closure ekon16
A closure ekon16
Max Kleiner
 
Exciting JavaScript - Part I
Exciting JavaScript - Part I
Eugene Lazutkin
 
Clojurescript slides
Clojurescript slides
elliando dias
 
A Re-Introduction to JavaScript
A Re-Introduction to JavaScript
Simon Willison
 
Smalltalk, the dynamic language
Smalltalk, the dynamic language
mohamedsamyali
 
I know Java, why should I consider Clojure?
I know Java, why should I consider Clojure?
sbjug
 
ClojureScript Anatomy
ClojureScript Anatomy
Mike Fogus
 
Introduction to JavaScript for Modern Software Development
Introduction to JavaScript for Modern Software Development
Kenneth Geisshirt
 
Ad

Recently uploaded (20)

Oracle Cloud Infrastructure Generative AI Professional
Oracle Cloud Infrastructure Generative AI Professional
VICTOR MAESTRE RAMIREZ
 
Enabling BIM / GIS integrations with Other Systems with FME
Enabling BIM / GIS integrations with Other Systems with FME
Safe Software
 
Bridging the divide: A conversation on tariffs today in the book industry - T...
Bridging the divide: A conversation on tariffs today in the book industry - T...
BookNet Canada
 
TrustArc Webinar - 2025 Global Privacy Survey
TrustArc Webinar - 2025 Global Privacy Survey
TrustArc
 
Integration of Utility Data into 3D BIM Models Using a 3D Solids Modeling Wor...
Integration of Utility Data into 3D BIM Models Using a 3D Solids Modeling Wor...
Safe Software
 
Murdledescargadarkweb.pdfvolumen1 100 elementary
Murdledescargadarkweb.pdfvolumen1 100 elementary
JorgeSemperteguiMont
 
Scaling GenAI Inference From Prototype to Production: Real-World Lessons in S...
Scaling GenAI Inference From Prototype to Production: Real-World Lessons in S...
Anish Kumar
 
June Patch Tuesday
June Patch Tuesday
Ivanti
 
FME for Distribution & Transmission Integrity Management Program (DIMP & TIMP)
FME for Distribution & Transmission Integrity Management Program (DIMP & TIMP)
Safe Software
 
MuleSoft for AgentForce : Topic Center and API Catalog
MuleSoft for AgentForce : Topic Center and API Catalog
shyamraj55
 
PyData - Graph Theory for Multi-Agent Integration
PyData - Graph Theory for Multi-Agent Integration
barqawicloud
 
Your startup on AWS - How to architect and maintain a Lean and Mean account J...
Your startup on AWS - How to architect and maintain a Lean and Mean account J...
angelo60207
 
Floods in Valencia: Two FME-Powered Stories of Data Resilience
Floods in Valencia: Two FME-Powered Stories of Data Resilience
Safe Software
 
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
AmirStern2
 
Viral>Wondershare Filmora 14.5.18.12900 Crack Free Download
Viral>Wondershare Filmora 14.5.18.12900 Crack Free Download
Puppy jhon
 
Introduction to Typescript - GDG On Campus EUE
Introduction to Typescript - GDG On Campus EUE
Google Developer Group On Campus European Universities in Egypt
 
Edge-banding-machines-edgeteq-s-200-en-.pdf
Edge-banding-machines-edgeteq-s-200-en-.pdf
AmirStern2
 
Reducing Conflicts and Increasing Safety Along the Cycling Networks of East-F...
Reducing Conflicts and Increasing Safety Along the Cycling Networks of East-F...
Safe Software
 
Providing an OGC API Processes REST Interface for FME Flow
Providing an OGC API Processes REST Interface for FME Flow
Safe Software
 
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
SOFTTECHHUB
 
Oracle Cloud Infrastructure Generative AI Professional
Oracle Cloud Infrastructure Generative AI Professional
VICTOR MAESTRE RAMIREZ
 
Enabling BIM / GIS integrations with Other Systems with FME
Enabling BIM / GIS integrations with Other Systems with FME
Safe Software
 
Bridging the divide: A conversation on tariffs today in the book industry - T...
Bridging the divide: A conversation on tariffs today in the book industry - T...
BookNet Canada
 
TrustArc Webinar - 2025 Global Privacy Survey
TrustArc Webinar - 2025 Global Privacy Survey
TrustArc
 
Integration of Utility Data into 3D BIM Models Using a 3D Solids Modeling Wor...
Integration of Utility Data into 3D BIM Models Using a 3D Solids Modeling Wor...
Safe Software
 
Murdledescargadarkweb.pdfvolumen1 100 elementary
Murdledescargadarkweb.pdfvolumen1 100 elementary
JorgeSemperteguiMont
 
Scaling GenAI Inference From Prototype to Production: Real-World Lessons in S...
Scaling GenAI Inference From Prototype to Production: Real-World Lessons in S...
Anish Kumar
 
June Patch Tuesday
June Patch Tuesday
Ivanti
 
FME for Distribution & Transmission Integrity Management Program (DIMP & TIMP)
FME for Distribution & Transmission Integrity Management Program (DIMP & TIMP)
Safe Software
 
MuleSoft for AgentForce : Topic Center and API Catalog
MuleSoft for AgentForce : Topic Center and API Catalog
shyamraj55
 
PyData - Graph Theory for Multi-Agent Integration
PyData - Graph Theory for Multi-Agent Integration
barqawicloud
 
Your startup on AWS - How to architect and maintain a Lean and Mean account J...
Your startup on AWS - How to architect and maintain a Lean and Mean account J...
angelo60207
 
Floods in Valencia: Two FME-Powered Stories of Data Resilience
Floods in Valencia: Two FME-Powered Stories of Data Resilience
Safe Software
 
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
AmirStern2
 
Viral>Wondershare Filmora 14.5.18.12900 Crack Free Download
Viral>Wondershare Filmora 14.5.18.12900 Crack Free Download
Puppy jhon
 
Edge-banding-machines-edgeteq-s-200-en-.pdf
Edge-banding-machines-edgeteq-s-200-en-.pdf
AmirStern2
 
Reducing Conflicts and Increasing Safety Along the Cycling Networks of East-F...
Reducing Conflicts and Increasing Safety Along the Cycling Networks of East-F...
Safe Software
 
Providing an OGC API Processes REST Interface for FME Flow
Providing an OGC API Processes REST Interface for FME Flow
Safe Software
 
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
AudGram Review: Build Visually Appealing, AI-Enhanced Audiograms to Engage Yo...
SOFTTECHHUB
 
Ad

The Parenscript Common Lisp to JavaScript compiler

  • 1. The Parenscript Common Lisp to JavaScript compiler Vladimir Sedach <[email protected]>
  • 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.)