README.org (3973 bytes)
1 #+TITLE: SL: A Package Dependency Language 2 #+AUTHOR: Spenser Truex 3 #+EMAIL: web@spensertruex.com 4 5 Version 1.0 is out! 6 7 [[https://github.com/equwal/sl][Github]] | [[https://equwal.com/sl--dependency-language][Homepage]] 8 9 SL is a complex dependency fixer. 10 11 Use SL to support two wildly different forks of a library like swank 12 and slynk. 13 14 #+BEGIN_SRC 15 (defsl operator-arglist :fn :eq slynk swank) 16 #+END_SRC 17 18 SL is a Domain Specific Language (ie. simple programming language) for dealing 19 with ambiguous dependency situations. It is more expressive than the standard 20 method in Common Lisp: the use of reader macros. It provides symbol aliasing 21 based on compile-time rules. 22 23 Symbols are then defined in the SL package, which is an artifact of the 24 fact that it was designed primarily to allow supporting both the slynk 25 and swank language servers. 26 27 TODO: allow defining them in other packages 28 29 * Rationale and Purpose 30 31 I made this since =asdf= was not enough abstraction for what I needed: to 32 arbitrarily choose dependencies and renames for any symbol. I could write what I 33 am doing twice, or I could write the compiler for =SL= (ie. the first two 34 letters of SLy and SLime). Once I have that, I can bend that fork until I have a 35 coherent set of names for all the functions I need, and which work on both (in 36 principle). You could just intern the symbols (like with #+ reader syntax) but 37 those tend to explode exponentially; since SL is using the compiler, 38 a much more powerful solution is implemented in macros. 39 40 * Benefits 41 42 - Symbol aliasing at compile time provides a means of abstracting separate 43 but similar interfaces. Forked projects, or projects that duplicate work. 44 - Far more expressive and concise than reader macros, while still very simple. 45 - There is also the use case of renaming things for import, like 46 =with-gensyms= to =with-unique-names= or similar. 47 48 * Drawbacks 49 50 none 51 52 * Examples 53 54 The only external macro is =defsl=. There is BNF below, though some examples are in order. 55 56 ** Simple 57 This defines =operator-arglist= (in the current package) as 58 =slynk:operator-arglist=, unless =slynk= is unavailable, in which case 59 =swank:operator-arglist= is used. 60 61 #+BEGIN_SRC lisp 62 (defsl operator-arglist :fn :eq slynk swank) 63 #+END_SRC 64 65 The =:fn= shows that a FUNCTION is being defined, as opposed to a =:sym= symbol; 66 to define another namespace a list is required: =(accessor-fn boundp-fn)=. =:eq= 67 denotes that the packages have the same name for this function. 68 For this simplest of examples, consider the reader macro alternative. 69 70 #+BEGIN_SRC lisp 71 #+slynk 72 (setf (symbol-function 'operator-arglist) 73 slynk:operator-arglist) 74 #+(and (not slynk) swank) 75 (setf (symbol-function 'operator-arglist) 76 swank:operator-arglist) 77 #+END_SRC 78 79 ** Complex example 80 81 #+BEGIN_SRC lisp 82 (defsl gensymmer (macro-function macro-function) 83 utils with-unique-names 84 alexandria with-gensyms) 85 #+END_SRC 86 87 To break this down: 88 - =sl:gensymmer= is now defined as =utils:with-unique-names=. 89 - =macro-function= was used twice: once as a =setfable= place, and once as a 90 predicate. 91 - If the =utils= package does not exist, then =sl:gensymmer= is defined as =alexanrdia:with-gensyms=. 92 - to define different names for each package, they must be "qualified" with the package name. 93 94 * Install 95 Use ASDF to install. Usually this should work: 96 #+BEGIN_SRC sh 97 $ cd ~/common-lisp/ 98 $ git clone git@github.com:equwal/sl.git 99 CL-USER> (asdf:load-system :sl) 100 #+END_SRC 101 102 * BNF 103 #+BEGIN_EXAMPLE 104 (defsl <sl-name> <fnsym> <package spec>) 105 <package spec> ::= <eq> 106 | <packages> 107 <eq> ::= :eq <preferences> 108 <fnsym> ::= :fn 109 | :sym 110 | <fnpair> 111 112 <fnpair> ::= (setfable-place bound-predicate) 113 <packages> ::= <package> <fn name> <more packages> 114 <package> ::= symbol 115 <fn name> ::= symbol 116 <preferences> ::= <package> <more packages> 117 <more packages> ::= ε 118 | <package> 119 | <package> <more packages> 120 #+END_EXAMPLE 121 * Non-issues: 122 - defsl is a hygienic macro