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
ย 
Os Harkins
Os HarkinsOs Harkins
Os Harkins
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

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
ย 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
ย 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
ย 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
ย 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
Christopher Logan Kennedy
ย 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(โ˜Ž๏ธ+971_581248768%)**%*]'#abortion pills for sale in dubai@
ย 

Recently uploaded (20)

Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
ย 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
ย 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
ย 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
ย 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
ย 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
ย 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
ย 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
ย 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
ย 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
ย 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
ย 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
ย 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
ย 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
ย 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
ย 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
ย 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
ย 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
ย 
Elevate Developer Efficiency & build GenAI Application with Amazon Qโ€‹
Elevate Developer Efficiency & build GenAI Application with Amazon Qโ€‹Elevate Developer Efficiency & build GenAI Application with Amazon Qโ€‹
Elevate Developer Efficiency & build GenAI Application with Amazon Qโ€‹
ย 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
ย 

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.)