SlideShare a Scribd company logo
1 of 33
Download to read offline
Loading Multiple Versions
of an ASDF System in the
Same Lisp Image
Vsevolod Domkin
10th
European Lisp Symposium
2017-04-03
It all started with ...
I'm yet to see a name
conflict in Lisp that can't
be solved by application of
rename-package
-- a not-exact quote by Xach Beane (?)
Heard about adversarial learning?
Outline
* “Dependency Hell” problem and
solutions
* Lisp package system and relevant
facilities
* ASDF, its APIs & limitations
* Conflict scenarios
* Our solution to name conflict
resolution: its properties,
limitations and how it works
on/around ASDF
* Conclusions and future work
Module name/version
conflicts
Dependency hell arises around shared
packages or libraries on which several
other packages have dependencies but
where they depend on different and
incompatible versions of the shared
packages. [Wikipedia]
Also known as: “dll hell”, “jar hell”
Its manifestation
in the CL ecosystem
* Unrelated packages' name clashes:
reported conflict for “bt” nickname
in Quicklisp (among 1400+ libraries):
bordeaux-threads vs binary-types
* potential conflict between versions
of the same system
Solution in most
languages
“In a particularly sad situation, you may find
that you have two dependencies that depend on
very incompatible versions of a common
transitive dependency. Ideally, you should try
to update one of your dependencies to use a
newer version of the shared library. If you
can’t do this, a good backup plan is to
unleash a tormented wail and weep into your
keyboard.”
-- The Nine Circles of Python Dependency Hell
(https://goo.gl/2WfTnh)
Java
* custom classloader
URLClassLoader clsLoader = URLClassLoader.newInstance(
new URL[] {new URL("file:/C://Test/test.jar")});
Class cls = clsLoader.loadClass("test.Main");
Method method = cls.getMethod("main", String[].class);
String[]params = new String[2];
method.invoke(null, (Object) params);
* OSGi
* project Jigsaw
Javascript
Node.js require
// module.js
exports.hello = function() { return "Hello"; }
// main.js
const myModule = require('./module');
let val = myModule.hello();
ES6 imports
// module.js
export function hello() { return "Hello"; }
// main.js
import {hello} from 'module';
let val = hello();
Common Lisp
Package facility
* Packages are centrally-accessible
dynamic singleton objects that hold
references to symbols
* Package namespace is
non-hierarchical
* Packages may have nicknames
* Packages may be redefined and
renamed
Idea
In the case of a name conflict, use
rename-package to alter the name of
one the first conflicting package
before loading the second one.
Potential pitfalls:
- conflict discovery
- choosing the proper time to rename
the package
- limits the subsequent use of
eval & intern
Common Lisp
System facility
* Packages provide namespacing,
systems provide packaging
* ASDF a de facto standard–
* ASDF in many ways resembles the
package system: e.g. find-system is
modelled after find-package
* Package discovery and distribution
built on top of ASDF (see Quicklisp)
* A name conflict solution should be
built on top of package & system
facilities
Limitation of ASDF
Likewise with package, it has a
central in-memory registry of known
systems with a 1-to-1 name-system
correspondence.
ASDF supports system versioning, but
only marginally:
- only 1 system version may be known
- you can't call find-system with a
version argument
- ASDF ops (like load-op) may take
version as argument, but use it
passively (as a constraint)
Critique of ASDF
* its ops are not referentially-
transparent and not fully-extensible
* it's is a great tool, but it doesn't
(yet) realize its potential to
become a framework for building on
top of it
* its mid-level API is not complete,
neither it is documented
ASDF can't
* load a system from a specific
filesystem location
* enumerate all potential candidate
locations for loading a system
* find a system with a specified version
* load just the source files for the
system's components without
potentially reloading its dependencies
* read the contents of an ASDF system
definition without changing the global
state
Basic cases
“zero” (do nothing)
Basic cases
“zero” (do nothing)
“basic” conflict
resolution required
Basic cases (2)
“subroot” “cross”
Basic cases (3)
“inter” “subinter”
Algorithm
1.Assemble the dependency tree for
the system to be loaded based on
ASDF systems' dependency information
and, using it, discover the
dependencies, which produce name
conflicts.
2.In case of no conflicts, fall back
to regular ASDF load sequence.
3.In case of conflicts, for each
conflicting system determine the
topmost possible user that doesn't
have two conflicting dependencies.
Algorithm (2)
4.Determine the load order of systems
using topological sort with an
additional constraint that, among
the children of the current node of
the dependency tree, the ones that
require conflict resolution will be
loaded in proper order.
5.Load the system's components
(without loading the dependencies)
in the determined order recording
the fact of visiting a particular
system to avoid reloading
of the same dependencies.
Algorithm (3)
6.During the load process, record all
package additions and associate them
with the system being loaded.
7.After a particular system has been
loaded, check whether it was
determined as a point of renaming
for one or more of its dependencies,
and perform the renaming
(if necessary).
(defun load-system-with-renamings (sys)
(multiple-value-bind (deps load-order renamings)
(traverse-dep-tree sys)
(when (zerop (hash-table-count renamings))
(return-from load-system-with-renamings
(asdf:load-system sys)))
(let ((already-loaded (make-hash-table :test 'equal))
(dep-packages (make-hash-table)))
;; load dependencies one by one in topological sort
;; order renaming packages when necessary and
;; caching the results
(dolist (dep load-order)
(let ((conflict (detect-conflict)))
(when (or conflict
(not (gethash (sys-name dep)
already-loaded)))
(renaming-packages
(if conflict
(load-system dep)
(load-components
(asdf:find-system (sys-name dep)))))
(unless conflict
(setf (gethash name already-loaded) t)))))))))
(defmacro renaming-packages (&body body)
`(let ((known-packages (list-all-packages)))
,@body
;; record newly added packages
(setf (gethash dep dep-packages)
(set-difference (list-all-packages)
known-packages))
;; it's safe to rename pending packages now
(dolist (d (gethash dep renamings)))
(let ((suff (format nil "~:@(~A-~A-~A~)"
(sys-version d) (sys-name dep)
(gensym))))
(dolist (pkg (gethash d dep-packages))
(rename-package
pkg
(format nil "~A-~A"
(package-name package) suff)
(mapcar (lambda (nickname)
(format nil "~A-~A" nickname suff))
(package-nicknames pkg))))))
Limitations of
this approach
* passive capture of package changes
* intended for automatic scenarios -
may mess up ad hoc interactive
workflows
* doesn't handle monkey-patching
* doesn't handle implicit transitive
Dependencies
* plus a couple of implementation
details
ASDF quiz
* How to get a record of a particular
ASDF system when you know its .asd file?
ASDF quiz
* How to get a record of a particular
ASDF system when you know its .asd file?
(asdf:load-asd asd)
(cdr (asdf:system-registered-p system))
ASDF quiz (2)
* How do you find all candidate .asd
systems in your “search path”?
ASDF quiz (2)
* How do you find all candidate .asd
systems in your “search path”?
(defun sysdef-exhaustive-central-registry-search (system)
(let ((name (asdf:primary-system-name system))
rez)
(dolist (dir asdf:*central-registry*)
(let ((defaults (eval dir)))
(when (and defaults
(uiop:directory-pathname-p defaults))
(let ((file (asdf::probe-asd
name defaults
:truename asdf:*resolve-symlinks*)))
(when file
(push file rez))))))
(reverse rez))))
ASDF quiz (3)
* How do you load just the system's
Components without reloading all of
its dependencies
(and upgrading ASDF in the process)?
ASDF quiz (3)
* How do you load just the system's
Components without reloading all of
its dependencies
(and upgrading ASDF in the process)?
(defparameter *loading-with-renamings* nil)
(defmethod asdf:component-depends-on
:around ((o asdf:prepare-op) (s asdf:system))
(unless *loading-with-renamings*
(call-next-method)))
(defun load-components (sys)
(let ((*loading-with-renamings* t))
(dolist (c (asdf:module-components sys))
(asdf:operate 'asdf:load-op c)))
t)
Parting words
* It works :)
* But more work needs to be done to
make it not just useful but reusable
* “ASDFx”
Thanks for your
attention!
Vsevolod Domkin
http://vseloved.github.io
vseloved @ gmail/twitter/github/…
http://m8nware.com
(m8n)ware a Lisp company working on–
cognition-related computing problems

More Related Content

What's hot

Unix Commands
Unix CommandsUnix Commands
Unix Commands
Dr.Ravi
 
Chapter 4 2
Chapter 4 2Chapter 4 2
Chapter 4 2
lopjuan
 
Applecmdlista zs
Applecmdlista zsApplecmdlista zs
Applecmdlista zs
Ben Pope
 

What's hot (20)

Unix Basics For Testers
Unix Basics For TestersUnix Basics For Testers
Unix Basics For Testers
 
Linux Shell Basics
Linux Shell BasicsLinux Shell Basics
Linux Shell Basics
 
Systemcall1
Systemcall1Systemcall1
Systemcall1
 
Perl for System Automation - 01 Advanced File Processing
Perl for System Automation - 01 Advanced File ProcessingPerl for System Automation - 01 Advanced File Processing
Perl for System Automation - 01 Advanced File Processing
 
Perl Programming - 03 Programming File
Perl Programming - 03 Programming FilePerl Programming - 03 Programming File
Perl Programming - 03 Programming File
 
Introduction to-linux
Introduction to-linuxIntroduction to-linux
Introduction to-linux
 
Unix Commands
Unix CommandsUnix Commands
Unix Commands
 
Introduction to linux day-3
Introduction to linux day-3Introduction to linux day-3
Introduction to linux day-3
 
Unix Basics Commands
Unix Basics CommandsUnix Basics Commands
Unix Basics Commands
 
Chapter 4 2
Chapter 4 2Chapter 4 2
Chapter 4 2
 
Perl Programming - 01 Basic Perl
Perl Programming - 01 Basic PerlPerl Programming - 01 Basic Perl
Perl Programming - 01 Basic Perl
 
Shell programming
Shell programmingShell programming
Shell programming
 
Chapter 2 unix system commands
Chapter 2 unix system commandsChapter 2 unix system commands
Chapter 2 unix system commands
 
Applecmdlista zs
Applecmdlista zsApplecmdlista zs
Applecmdlista zs
 
intro unix/linux 08
intro unix/linux 08intro unix/linux 08
intro unix/linux 08
 
Command Line Tools
Command Line ToolsCommand Line Tools
Command Line Tools
 
intro unix/linux 02
intro unix/linux 02intro unix/linux 02
intro unix/linux 02
 
Complete Guide for Linux shell programming
Complete Guide for Linux shell programmingComplete Guide for Linux shell programming
Complete Guide for Linux shell programming
 
Examples -partII
Examples -partIIExamples -partII
Examples -partII
 
Course 102: Lecture 10: Learning About the Shell
Course 102: Lecture 10: Learning About the Shell Course 102: Lecture 10: Learning About the Shell
Course 102: Lecture 10: Learning About the Shell
 

Similar to Loading Multiple Versions of an ASDF System in the Same Lisp Image

5.Shell And Environment
5.Shell And Environment5.Shell And Environment
5.Shell And Environment
phanleson
 
dylibencapsulation
dylibencapsulationdylibencapsulation
dylibencapsulation
Cole Herzog
 
1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx
 1 CMPS 12M Data Structures Lab Lab Assignment 1  .docx 1 CMPS 12M Data Structures Lab Lab Assignment 1  .docx
1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx
joyjonna282
 
1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx
1 CMPS 12M Data Structures Lab Lab Assignment 1  .docx1 CMPS 12M Data Structures Lab Lab Assignment 1  .docx
1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx
tarifarmarie
 
Spack - A Package Manager for HPC
Spack - A Package Manager for HPCSpack - A Package Manager for HPC
Spack - A Package Manager for HPC
inside-BigData.com
 
1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx
1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx
1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx
tarifarmarie
 
dotCloud (now Docker) Paas under the_hood
dotCloud (now Docker) Paas under the_hood dotCloud (now Docker) Paas under the_hood
dotCloud (now Docker) Paas under the_hood
Susan Wu
 
1 of 9 CSCE 3600 Systems Programming Major Assignm.docx
  1 of 9 CSCE 3600 Systems Programming  Major Assignm.docx  1 of 9 CSCE 3600 Systems Programming  Major Assignm.docx
1 of 9 CSCE 3600 Systems Programming Major Assignm.docx
ShiraPrater50
 

Similar to Loading Multiple Versions of an ASDF System in the Same Lisp Image (20)

File Context
File ContextFile Context
File Context
 
5.Shell And Environment
5.Shell And Environment5.Shell And Environment
5.Shell And Environment
 
Root file system for embedded systems
Root file system for embedded systemsRoot file system for embedded systems
Root file system for embedded systems
 
dylibencapsulation
dylibencapsulationdylibencapsulation
dylibencapsulation
 
1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx
 1 CMPS 12M Data Structures Lab Lab Assignment 1  .docx 1 CMPS 12M Data Structures Lab Lab Assignment 1  .docx
1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx
 
1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx
1 CMPS 12M Data Structures Lab Lab Assignment 1  .docx1 CMPS 12M Data Structures Lab Lab Assignment 1  .docx
1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx
 
Linux shell scripting
Linux shell scriptingLinux shell scripting
Linux shell scripting
 
Refcard en-a4
Refcard en-a4Refcard en-a4
Refcard en-a4
 
CIT173_Ch15_Mnstr_23.pdf
CIT173_Ch15_Mnstr_23.pdfCIT173_Ch15_Mnstr_23.pdf
CIT173_Ch15_Mnstr_23.pdf
 
Spack - A Package Manager for HPC
Spack - A Package Manager for HPCSpack - A Package Manager for HPC
Spack - A Package Manager for HPC
 
1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx
1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx
1 CMPS 12M Data Structures Lab Lab Assignment 1 .docx
 
dotCloud (now Docker) Paas under the_hood
dotCloud (now Docker) Paas under the_hood dotCloud (now Docker) Paas under the_hood
dotCloud (now Docker) Paas under the_hood
 
History
HistoryHistory
History
 
Class notes(week 7) on packages
Class notes(week 7) on packagesClass notes(week 7) on packages
Class notes(week 7) on packages
 
1 of 9 CSCE 3600 Systems Programming Major Assignm.docx
  1 of 9 CSCE 3600 Systems Programming  Major Assignm.docx  1 of 9 CSCE 3600 Systems Programming  Major Assignm.docx
1 of 9 CSCE 3600 Systems Programming Major Assignm.docx
 
Linux
Linux Linux
Linux
 
도커 없이 컨테이너 만들기 5편 마운트 네임스페이스와 오버레이 파일시스템
도커 없이 컨테이너 만들기 5편 마운트 네임스페이스와 오버레이 파일시스템도커 없이 컨테이너 만들기 5편 마운트 네임스페이스와 오버레이 파일시스템
도커 없이 컨테이너 만들기 5편 마운트 네임스페이스와 오버레이 파일시스템
 
My History
My HistoryMy History
My History
 
Linux basic for CADD biologist
Linux basic for CADD biologistLinux basic for CADD biologist
Linux basic for CADD biologist
 
Linux Troubleshooting
Linux TroubleshootingLinux Troubleshooting
Linux Troubleshooting
 

More from Vsevolod Dyomkin

Natural Language Processing in Practice
Natural Language Processing in PracticeNatural Language Processing in Practice
Natural Language Processing in Practice
Vsevolod Dyomkin
 
Lisp как универсальная обертка
Lisp как универсальная оберткаLisp как универсальная обертка
Lisp как универсальная обертка
Vsevolod Dyomkin
 
Lisp for Python Programmers
Lisp for Python ProgrammersLisp for Python Programmers
Lisp for Python Programmers
Vsevolod Dyomkin
 
Tedxkyiv communication guidelines
Tedxkyiv communication guidelinesTedxkyiv communication guidelines
Tedxkyiv communication guidelines
Vsevolod Dyomkin
 
Новые нереляционные системы хранения данных
Новые нереляционные системы хранения данныхНовые нереляционные системы хранения данных
Новые нереляционные системы хранения данных
Vsevolod Dyomkin
 
Чему мы можем научиться у Lisp'а?
Чему мы можем научиться у Lisp'а?Чему мы можем научиться у Lisp'а?
Чему мы можем научиться у Lisp'а?
Vsevolod Dyomkin
 

More from Vsevolod Dyomkin (20)

NLP Project Full Circle
NLP Project Full CircleNLP Project Full Circle
NLP Project Full Circle
 
Lisp in a Startup: the Good, the Bad, and the Ugly
Lisp in a Startup: the Good, the Bad, and the UglyLisp in a Startup: the Good, the Bad, and the Ugly
Lisp in a Startup: the Good, the Bad, and the Ugly
 
The State of #NLProc
The State of #NLProcThe State of #NLProc
The State of #NLProc
 
NLP in the WILD or Building a System for Text Language Identification
NLP in the WILD or Building a System for Text Language IdentificationNLP in the WILD or Building a System for Text Language Identification
NLP in the WILD or Building a System for Text Language Identification
 
NLP Project Full Cycle
NLP Project Full CycleNLP Project Full Cycle
NLP Project Full Cycle
 
Sugaring Lisp for the 21st Century
Sugaring Lisp for the 21st CenturySugaring Lisp for the 21st Century
Sugaring Lisp for the 21st Century
 
Crash Course in Natural Language Processing (2016)
Crash Course in Natural Language Processing (2016)Crash Course in Natural Language Processing (2016)
Crash Course in Natural Language Processing (2016)
 
Can functional programming be liberated from static typing?
Can functional programming be liberated from static typing?Can functional programming be liberated from static typing?
Can functional programming be liberated from static typing?
 
Crash-course in Natural Language Processing
Crash-course in Natural Language ProcessingCrash-course in Natural Language Processing
Crash-course in Natural Language Processing
 
Lisp Machine Prunciples
Lisp Machine PrunciplesLisp Machine Prunciples
Lisp Machine Prunciples
 
Natural Language Processing in Practice
Natural Language Processing in PracticeNatural Language Processing in Practice
Natural Language Processing in Practice
 
CL-NLP
CL-NLPCL-NLP
CL-NLP
 
Lisp как универсальная обертка
Lisp как универсальная оберткаLisp как универсальная обертка
Lisp как универсальная обертка
 
Lisp for Python Programmers
Lisp for Python ProgrammersLisp for Python Programmers
Lisp for Python Programmers
 
Aspects of NLP Practice
Aspects of NLP PracticeAspects of NLP Practice
Aspects of NLP Practice
 
Practical NLP with Lisp
Practical NLP with LispPractical NLP with Lisp
Practical NLP with Lisp
 
Tedxkyiv communication guidelines
Tedxkyiv communication guidelinesTedxkyiv communication guidelines
Tedxkyiv communication guidelines
 
Новые нереляционные системы хранения данных
Новые нереляционные системы хранения данныхНовые нереляционные системы хранения данных
Новые нереляционные системы хранения данных
 
Чему мы можем научиться у Lisp'а?
Чему мы можем научиться у Lisp'а?Чему мы можем научиться у Lisp'а?
Чему мы можем научиться у Lisp'а?
 
Экосистема Common Lisp
Экосистема Common LispЭкосистема Common Lisp
Экосистема Common Lisp
 

Recently uploaded

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
 

Recently uploaded (20)

DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
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
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
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 ...
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
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
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
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
 
"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 ...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
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​
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 

Loading Multiple Versions of an ASDF System in the Same Lisp Image

  • 1. Loading Multiple Versions of an ASDF System in the Same Lisp Image Vsevolod Domkin 10th European Lisp Symposium 2017-04-03
  • 2. It all started with ... I'm yet to see a name conflict in Lisp that can't be solved by application of rename-package -- a not-exact quote by Xach Beane (?)
  • 4. Outline * “Dependency Hell” problem and solutions * Lisp package system and relevant facilities * ASDF, its APIs & limitations * Conflict scenarios * Our solution to name conflict resolution: its properties, limitations and how it works on/around ASDF * Conclusions and future work
  • 5. Module name/version conflicts Dependency hell arises around shared packages or libraries on which several other packages have dependencies but where they depend on different and incompatible versions of the shared packages. [Wikipedia] Also known as: “dll hell”, “jar hell”
  • 6. Its manifestation in the CL ecosystem * Unrelated packages' name clashes: reported conflict for “bt” nickname in Quicklisp (among 1400+ libraries): bordeaux-threads vs binary-types * potential conflict between versions of the same system
  • 7. Solution in most languages “In a particularly sad situation, you may find that you have two dependencies that depend on very incompatible versions of a common transitive dependency. Ideally, you should try to update one of your dependencies to use a newer version of the shared library. If you can’t do this, a good backup plan is to unleash a tormented wail and weep into your keyboard.” -- The Nine Circles of Python Dependency Hell (https://goo.gl/2WfTnh)
  • 8. Java * custom classloader URLClassLoader clsLoader = URLClassLoader.newInstance( new URL[] {new URL("file:/C://Test/test.jar")}); Class cls = clsLoader.loadClass("test.Main"); Method method = cls.getMethod("main", String[].class); String[]params = new String[2]; method.invoke(null, (Object) params); * OSGi * project Jigsaw
  • 9. Javascript Node.js require // module.js exports.hello = function() { return "Hello"; } // main.js const myModule = require('./module'); let val = myModule.hello(); ES6 imports // module.js export function hello() { return "Hello"; } // main.js import {hello} from 'module'; let val = hello();
  • 10. Common Lisp Package facility * Packages are centrally-accessible dynamic singleton objects that hold references to symbols * Package namespace is non-hierarchical * Packages may have nicknames * Packages may be redefined and renamed
  • 11. Idea In the case of a name conflict, use rename-package to alter the name of one the first conflicting package before loading the second one. Potential pitfalls: - conflict discovery - choosing the proper time to rename the package - limits the subsequent use of eval & intern
  • 12. Common Lisp System facility * Packages provide namespacing, systems provide packaging * ASDF a de facto standard– * ASDF in many ways resembles the package system: e.g. find-system is modelled after find-package * Package discovery and distribution built on top of ASDF (see Quicklisp) * A name conflict solution should be built on top of package & system facilities
  • 13. Limitation of ASDF Likewise with package, it has a central in-memory registry of known systems with a 1-to-1 name-system correspondence. ASDF supports system versioning, but only marginally: - only 1 system version may be known - you can't call find-system with a version argument - ASDF ops (like load-op) may take version as argument, but use it passively (as a constraint)
  • 14. Critique of ASDF * its ops are not referentially- transparent and not fully-extensible * it's is a great tool, but it doesn't (yet) realize its potential to become a framework for building on top of it * its mid-level API is not complete, neither it is documented
  • 15. ASDF can't * load a system from a specific filesystem location * enumerate all potential candidate locations for loading a system * find a system with a specified version * load just the source files for the system's components without potentially reloading its dependencies * read the contents of an ASDF system definition without changing the global state
  • 17. Basic cases “zero” (do nothing) “basic” conflict resolution required
  • 19. Basic cases (3) “inter” “subinter”
  • 20. Algorithm 1.Assemble the dependency tree for the system to be loaded based on ASDF systems' dependency information and, using it, discover the dependencies, which produce name conflicts. 2.In case of no conflicts, fall back to regular ASDF load sequence. 3.In case of conflicts, for each conflicting system determine the topmost possible user that doesn't have two conflicting dependencies.
  • 21. Algorithm (2) 4.Determine the load order of systems using topological sort with an additional constraint that, among the children of the current node of the dependency tree, the ones that require conflict resolution will be loaded in proper order. 5.Load the system's components (without loading the dependencies) in the determined order recording the fact of visiting a particular system to avoid reloading of the same dependencies.
  • 22. Algorithm (3) 6.During the load process, record all package additions and associate them with the system being loaded. 7.After a particular system has been loaded, check whether it was determined as a point of renaming for one or more of its dependencies, and perform the renaming (if necessary).
  • 23. (defun load-system-with-renamings (sys) (multiple-value-bind (deps load-order renamings) (traverse-dep-tree sys) (when (zerop (hash-table-count renamings)) (return-from load-system-with-renamings (asdf:load-system sys))) (let ((already-loaded (make-hash-table :test 'equal)) (dep-packages (make-hash-table))) ;; load dependencies one by one in topological sort ;; order renaming packages when necessary and ;; caching the results (dolist (dep load-order) (let ((conflict (detect-conflict))) (when (or conflict (not (gethash (sys-name dep) already-loaded))) (renaming-packages (if conflict (load-system dep) (load-components (asdf:find-system (sys-name dep))))) (unless conflict (setf (gethash name already-loaded) t)))))))))
  • 24. (defmacro renaming-packages (&body body) `(let ((known-packages (list-all-packages))) ,@body ;; record newly added packages (setf (gethash dep dep-packages) (set-difference (list-all-packages) known-packages)) ;; it's safe to rename pending packages now (dolist (d (gethash dep renamings))) (let ((suff (format nil "~:@(~A-~A-~A~)" (sys-version d) (sys-name dep) (gensym)))) (dolist (pkg (gethash d dep-packages)) (rename-package pkg (format nil "~A-~A" (package-name package) suff) (mapcar (lambda (nickname) (format nil "~A-~A" nickname suff)) (package-nicknames pkg))))))
  • 25. Limitations of this approach * passive capture of package changes * intended for automatic scenarios - may mess up ad hoc interactive workflows * doesn't handle monkey-patching * doesn't handle implicit transitive Dependencies * plus a couple of implementation details
  • 26. ASDF quiz * How to get a record of a particular ASDF system when you know its .asd file?
  • 27. ASDF quiz * How to get a record of a particular ASDF system when you know its .asd file? (asdf:load-asd asd) (cdr (asdf:system-registered-p system))
  • 28. ASDF quiz (2) * How do you find all candidate .asd systems in your “search path”?
  • 29. ASDF quiz (2) * How do you find all candidate .asd systems in your “search path”? (defun sysdef-exhaustive-central-registry-search (system) (let ((name (asdf:primary-system-name system)) rez) (dolist (dir asdf:*central-registry*) (let ((defaults (eval dir))) (when (and defaults (uiop:directory-pathname-p defaults)) (let ((file (asdf::probe-asd name defaults :truename asdf:*resolve-symlinks*))) (when file (push file rez)))))) (reverse rez))))
  • 30. ASDF quiz (3) * How do you load just the system's Components without reloading all of its dependencies (and upgrading ASDF in the process)?
  • 31. ASDF quiz (3) * How do you load just the system's Components without reloading all of its dependencies (and upgrading ASDF in the process)? (defparameter *loading-with-renamings* nil) (defmethod asdf:component-depends-on :around ((o asdf:prepare-op) (s asdf:system)) (unless *loading-with-renamings* (call-next-method))) (defun load-components (sys) (let ((*loading-with-renamings* t)) (dolist (c (asdf:module-components sys)) (asdf:operate 'asdf:load-op c))) t)
  • 32. Parting words * It works :) * But more work needs to be done to make it not just useful but reusable * “ASDFx”
  • 33. Thanks for your attention! Vsevolod Domkin http://vseloved.github.io vseloved @ gmail/twitter/github/… http://m8nware.com (m8n)ware a Lisp company working on– cognition-related computing problems