alex-gutev / cl-environments Goto Github PK
View Code? Open in Web Editor NEWImplements the CLTL2 environment access API.
Home Page: https://alex-gutev.github.io/cl-environments/
License: MIT License
Implements the CLTL2 environment access API.
Home Page: https://alex-gutev.github.io/cl-environments/
License: MIT License
Feel free to close this if it's a non-issue, but I noticed that on SBCL, Allegro and LispWorks, (maybe others? Sorry, unfamiliar with the project structure), the cl-environments
package will export all symbols in CL.
Is there a specific reason for this?
Is it possible to remove the optima dependency? There seems to be only one pattern. The reason is licensing; although cl-environments is MIT licensed, the transitive dependency, optima, has a restrictive license, meaning cl-environments can't be used where such licenses are not allowed.
Happy to help strip it out if this is something can be done without a huge amount of effort.
About define-declaration
, CLTL2 writes:
The function defined by this macro will be called with two arguments, a declaration specifier whose car is decl-name and the env argument to augment-environment.
For the following:
(define-declaration my-decl (args)
(print args)
(values :variable nil))
CCL provides the args as a list whose first element is indeed the decl-name
, while SBCL does not.
(augment-environment nil :variable '(x) :declare '((my-decl x)))
; prints (MY-DECL X) on CCL
; prints (X) on SBCL
CLHS allows lambdas to have a documentation string:
CL-USER> (documentation (lambda (x) "hello" (declare (ignorable x)) x) 'function)
"hello"
Thus, both of the following should work, however, in the presence of documentation string, on implementations like CCL, the declarations get put inside the symbol-macrolet conveying the environment information. This does not occur in the absence of the documentation string.
CL-ENVIRONMENTS> (cl-environments.cltl2::%walk-form (cl:lambda (x)
(declare (ignore x))))
#<Anonymous Function #x302001E30B8F>
CL-ENVIRONMENTS> (cl-environments.cltl2::%walk-form (cl:lambda (x)
""
(declare (ignore x))))
; Evaluation aborted on #<CCL::COMPILE-TIME-PROGRAM-ERROR #x302001D6A8FD>
CL-ENVIRONMENTS> (macroexpand `(cl-environments.cltl2::%walk-form (cl:lambda (x)
""
(declare (ignore x)))))
#'(LAMBDA (X)
(COMMON-LISP:SYMBOL-MACROLET
((CL-ENVIRONMENTS.CLTL2::LOCAL-ENVIRONMENT-SYMBOL-MACRO
#<CL-ENVIRONMENTS.CLTL2::ENVIRONMENT #x302001F094CD>))
(CL-ENVIRONMENTS.CLTL2::%WALK-FORM "")
(CL-ENVIRONMENTS.CLTL2::%WALK-FORM (DECLARE (IGNORE X)))))
T
CL-ENVIRONMENTS> (macroexpand `(cl-environments.cltl2::%walk-form (cl:lambda (x)
(declare (ignore x)))))
#'(LAMBDA (X)
(DECLARE (IGNORE X))
(COMMON-LISP:SYMBOL-MACROLET
((CL-ENVIRONMENTS.CLTL2::LOCAL-ENVIRONMENT-SYMBOL-MACRO
#<CL-ENVIRONMENTS.CLTL2::ENVIRONMENT #x302001F0677D>))))
T
Error on CCL 1.12.1:
While compiling an anonymous function :
The DECLARE expression (DECLARE
(IGNORE X)) is being treated as a form,
possibly because it's the result of macroexpansion. DECLARE expressions
can only appear in specified contexts and must be actual subexpressions
of the containing forms.
[Condition of type CCL::COMPILE-TIME-PROGRAM-ERROR]
Restarts:
0: [CONTINUE] continue compilation ignoring this form
1: [RETRY] Retry SLIME REPL evaluation request.
2: [*ABORT] Return to SLIME's top level.
3: [ABORT-BREAK] Reset this thread
4: [ABORT] Kill this thread
Backtrace:
0: ((:INTERNAL CCL::NX1-COMPILE-LAMBDA) #<CCL::COMPILE-TIME-PROGRAM-ERROR #x302001F0393D>)
1: (SIGNAL #<CCL::COMPILE-TIME-PROGRAM-ERROR #x302001F0393D>)
2: (CCL::%ERROR #<CCL::COMPILE-TIME-PROGRAM-ERROR #x302001F0393D> NIL 17577650629554)
3: (CCL::NX-ERROR "The DECLARE expression ~s is being treated as a form,\npossibly because it's the result of macroexpansion. DECLARE expressions\ncan only appear in specified contexts and must be actual..
...
If I run (ql:quickload :cl-environments)
on SBCL 2.3.10, I encountered:
; caught ERROR:
; READ error during COMPILE-FILE:
;
; Symbol "TRULY-DYNAMIC-EXTENT" not found in the SB-INT package.
;
; Line: 162, Column: 44, File-Position: 464[8](https://github.com/hikettei/cl-waffe2/actions/runs/6752601846/job/18358141750#step:7:9)
;
; Stream: #<SB-INT:FORM-TRACKING-STREAM for "file /home/runner/.roswell/lisp/quicklisp/dists/quicklisp/software/cl-environments-20211020-git/src/other/sbcl.lisp" {1003DBA453}>
Unhandled UIOP/LISP-BUILD:COMPILE-FILE-ERROR in thread #<SB-THREAD:THREAD tid=2622 "main thread" RUNNING
{10013E00[9](https://github.com/hikettei/cl-waffe2/actions/runs/6752601846/job/18358141750#step:7:10)3}>:
COMPILE-FILE-ERROR while
compiling #<CL-SOURCE-FILE "cl-environments" "src" "other/sbcl">
Backtrace for: #<SB-THREAD:THREAD tid=2622 "main thread" RUNNING {[10](https://github.com/hikettei/cl-waffe2/actions/runs/6752601846/job/18358141750#step:7:11)0[13](https://github.com/hikettei/cl-waffe2/actions/runs/6752601846/job/18358141750#step:7:14)E0093}>
0: (SB-DEBUG::DEBUGGER-DISABLED-HOOK #<UIOP/LISP-BUILD:COMPILE-FILE-ERROR {10042A1F93}> #<unused argument> :QUIT T)
1: (SB-DEBUG::RUN-HOOK *INVOKE-DEBUGGER-HOOK* #<UIOP/LISP-BUILD:COMPILE-FILE-ERROR {10042A1F93}>)
2: (INVOKE-DEBUGGER #<UIOP/LISP-BUILD:COMPILE-FILE-ERROR {10042A1F93}>)
3: (ERROR UIOP/LISP-BUILD:COMPILE-FILE-ERROR :CONTEXT-FORMAT "~/asdf-action::format-action/" :CONTEXT-ARGUMENTS ((#<ASDF/LISP-ACTION:COMPILE-OP > . #<ASDF/LISP-ACTION:CL-SOURCE-FILE "cl-environments" "src" "other/sbcl">)))
4: (UIOP/LISP-BUILD:CHECK-LISP-COMPILE-RESULTS NIL T T "~/asdf-action::format-action/" ((#<ASDF/LISP-ACTION:COMPILE-OP > . #<ASDF/LISP-ACTION:CL-SOURCE-FILE "cl-environments" "src" "other/sbcl">)))
I suspect that this is due to any API changes related to SBCL update since if I change to use SBCL2.3.9, everything goes well.
When loading on LispWorks, I receive the following:
CL-USER 6 > (ql:quickload :cl-environments)
To load "cl-environments":
Load 1 ASDF system:
cl-environments
; Loading "cl-environments"
[package alexandria.0.dev]........................
[package anaphora]................................
[package anaphora-basic]..........................
[package anaphora-symbol].........................
[package closer-mop]..............................
[package closer-common-lisp]......................
[package closer-common-lisp-user].................
[package optima.core].............................
[package optima]..................................
[package optima.extra]............................
[package iterate].................................
[package symbol-munger]...........................
[package collectors-signals]......................
[package collectors]..............................
[package cl-environments.util]....................
[package cl-environments].
**++++ Error between functions:
Undefined operator REEXPORT-ALL-SYMBOLS in form (REEXPORT-ALL-SYMBOLS :CL).
; *** 1 error detected, no fasl file produced.
Error: COMPILE-FILE-ERROR while compiling
#<ASDF/LISP-ACTION:CL-SOURCE-FILE "cl-environments" "src" "other/lispworks">
1 (continue) Retry compiling
#<ASDF/LISP-ACTION:CL-SOURCE-FILE "cl-environments" "src" "other/lispworks">.
2 Continue, treating compiling
#<ASDF/LISP-ACTION:CL-SOURCE-FILE "cl-environments" "src" "other/lispworks">
as having been successful.
3 Retry ASDF operation.
4 Retry ASDF operation after resetting the configuration.
5 Retry ASDF operation.
6 Retry ASDF operation after resetting the configuration.
7 (abort) Give up on "cl-environments"
8 Return to level 0.
9 Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.
Looking at lispworks.lisp, looks like the package needs to :use
:cl-environments.util
as the other packages do.
I'll submit a PR
Depending on if I'm using mlisp or alisp, the errors are different; for alisp, it is:
Function position must contain a symbol or lambda expression:
(TYPE SYMBOL)
[Condition of type PARSE-ERROR]
Restarts:
0: [NIL] retry the compilation of /home/user/quicklisp/local-projects/cl-environments/src/other/allegro.lisp
1: [NIL] continue compiling /home/user/quicklisp/local-projects/cl-environments/src/other/allegro.lisp but generate no output file
2: [RETRY] Retry compiling #<CL-SOURCE-FILE "cl-environments" "src" "other/allegro">.
3: [ACCEPT] Continue, treating compiling #<CL-SOURCE-FILE "cl-environments" "src" "other/allegro"> as having been successful.
4: [RETRY] Retry ASDF operation.
5: [CLEAR-CONFIGURATION-AND-RETRY] Retry ASDF operation after resetting the configuration.
--more--
Backtrace:
0: (ERROR PARSE-ERROR :FORMAT-CONTROL "~?~@[~a~]" :FORMAT-ARGUMENTS ("~1@<Function position must contain a symbol or lambda expression: ~S~:@>" ((TYPE SYMBOL)) NIL))
1: (COMPILER::COMPILER-ERROR "Function position must contain a symbol or lambda expression: ~S" (TYPE SYMBOL))
While on mlisp, the error is:
cl-user> (ql:quickload "cl-environments")
To load "cl-environments":
Load 1 ASDF system:
cl-environments
; Loading "cl-environments"
Attempt to take the value of the unbound variable
`cl-environments.util::g!test'.
[Condition of type unbound-variable]
Restarts:
0: [try-again] Try evaluating cl-environments.util::g!test again.
1: [store-value] Set the symbol-value of cl-environments.util::g!test and use its value.
2: [use-value] Use a value without setting cl-environments.util::g!test.
3: [nil] retry the compilation of /home/user/quicklisp/local-projects/cl-environments/src/common/macro-util.lisp
4: [nil] continue compiling /home/user/quicklisp/local-projects/cl-environments/src/common/macro-util.lisp but generate no output file
5: [retry] Retry compiling #<cl-source-file "cl-environments" "src" "common" "macro-util">.
--more--
Backtrace:
0: (error #<unbound-variable @ #x20fdbdea>)
1: (cl-environments.util:let-if ..)
2: (funcall #<Macro Function let-if @ #x20d4870a> ..)
cl-environments/src/other/sbcl.lisp
Lines 213 to 214 in 1bd7ecf
Is there a reason why vars that are already special are being declared special?
Currently, the above leads to an error on the following. But not appending the special declaration fixes the issue.
CL-FORM-TYPES> (cl-form-types:nth-form-type `(handler-bind ((error (lambda (c)
(print c))))
(fun))
nil)
; Evaluation aborted on #<SB-KERNEL:CASE-FAILURE expected-type: (MEMBER :COMPILE :EVAL) datum: NIL>.
NIL fell through ECASE expression.
Wanted one of (:COMPILE :EVAL).
[Condition of type SB-KERNEL:CASE-FAILURE]
Restarts:
0: [IGNORE-ALL] Ignore all package locks in the context of this operation.
1: [UNLOCK-PACKAGE] Unlock the package.
2: [RETURN-DEFAULT-TYPE] RETURN-DEFAULT-TYPE
3: [RETRY] Retry SLIME REPL evaluation request.
4: [*ABORT] Return to SLIME's top level.
5: [ABORT] abort thread (#<THREAD tid=51785 "repl-thread" RUNNING {10014700A3}>)
Backtrace:
0: ((LAMBDA (CONDITION) :IN SB-KERNEL:PROGRAM-ASSERT-SYMBOL-HOME-PACKAGE-UNLOCKED) #<SB-EXT:SYMBOL-PACKAGE-LOCKED-ERROR "declaring ~A special" {100FB6F2B3}>)
1: (SB-KERNEL::%SIGNAL #<SB-EXT:SYMBOL-PACKAGE-LOCKED-ERROR "declaring ~A special" {100FB6F2B3}>)
2: (CERROR "Ignore the package lock." SB-EXT:SYMBOL-PACKAGE-LOCKED-ERROR :PACKAGE #<PACKAGE "SB-KERNEL"> :FORMAT-CONTROL "declaring ~A special" :FORMAT-ARGUMENTS (SB-KERNEL:*HANDLER-CLUSTERS*) :SYMBOL SB..
3: (SB-EXT:PACKAGE-LOCK-VIOLATION #<PACKAGE "SB-KERNEL"> :SYMBOL SB-KERNEL:*HANDLER-CLUSTERS* :FORMAT-CONTROL "declaring ~A special" :FORMAT-ARGUMENTS (SB-KERNEL:*HANDLER-CLUSTERS*))
4: (SB-KERNEL:ASSERT-SYMBOL-HOME-PACKAGE-UNLOCKED SB-KERNEL:*HANDLER-CLUSTERS* "declaring ~A special")
5: (SB-KERNEL:PROGRAM-ASSERT-SYMBOL-HOME-PACKAGE-UNLOCKED NIL SB-KERNEL:*HANDLER-CLUSTERS* "declaring ~A special")
6: (SB-C::PROCESS-1-DECL (SPECIAL SB-KERNEL:*HANDLER-CLUSTERS*) #<SB-KERNEL:LEXENV {100FB6F0F3}> (#<SB-C::LAMBDA-VAR :%SOURCE-NAME SB-KERNEL:*HANDLER-CLUSTERS* {100FB6F173}>) NIL NIL NIL)
7: ((FLET SB-C::PROCESS-IT :IN SB-C::PROCESS-DECLS) (SPECIAL SB-KERNEL:*HANDLER-CLUSTERS*) (DECLARE (SPECIAL SB-KERNEL:*HANDLER-CLUSTERS*) (DYNAMIC-EXTENT SB-KERNEL:*HANDLER-CLUSTERS*)))
8: (SB-C::PROCESS-DECLS ((DECLARE (SPECIAL SB-KERNEL:*HANDLER-CLUSTERS*) (DYNAMIC-EXTENT SB-KERNEL:*HANDLER-CLUSTERS*))) (#<SB-C::LAMBDA-VAR :%SOURCE-NAME SB-KERNEL:*HANDLER-CLUSTERS* {100FB6F173}>) NIL ..
9: (SB-CLTL2:AUGMENT-ENVIRONMENT #<unavailable argument> :VARIABLE (SB-KERNEL:*HANDLER-CLUSTERS*) :SYMBOL-MACRO NIL :FUNCTION NIL :MACRO NIL :DECLARE ((SPECIAL SB-KERNEL:*HANDLER-CLUSTERS*) (DYNAMIC-EXTE..
10: (LET-FORM-TYPE (((SB-KERNEL:*HANDLER-CLUSTERS* #)) (DECLARE (DYNAMIC-EXTENT SB-KERNEL:*HANDLER-CLUSTERS*)) (PROGN (FUN))) NIL)
For instance, on CCL:
(in-package :cl-user)
(defmacro var-type (var &environment env)
(print (multiple-value-list (cl-environments-cl:variable-information var env)))
var)
(cl-environments:define-declaration my-decl (vars)
(values :variable
(mapcar (lambda (x) (list x 'my-decl t)) vars)))
(defun foo (x)
(declare (my-decl x))
(var-type x))
; prints: (:LEXICAL T NIL)
(cl-environments-cl:defun foo (x)
(declare (my-decl x))
(var-type x))
; prints as expected: (:LEXICAL T ((MY-DECL . T)))
(cl-environments-cl:lambda (x)
(declare (my-decl x))
(var-type x))
; prints against expectation: (:LEXICAL T NIL)
This does seem to require shadowing lambda
, however, doing so also requires shadowing other forms such as define-condition
(through :report
) or even compile
that take lambda expressions.
(EDIT) Perhaps simpler although not the cleanest might be the introduction of a cltl2-lambda
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.