40ants / cl-prevalence Goto Github PK
View Code? Open in Web Editor NEWIn memory database system for Common Lisp
In memory database system for Common Lisp
Hi, I ran the tests and two failed.
Did 448 checks.
Pass: 446 (99%)
Skip: 0 ( 0%)
Fail: 2 ( 0%)
Failure Details:
--------------------------------
TEST-GET-SLAVE-USER in TEST-MASTER-SLAVE []:
Unexpected Error: #<USOCKET:ADDRESS-IN-USE-ERROR {1024902D33}>
Condition USOCKET:ADDRESS-IN-USE-ERROR was signalled..
--------------------------------
--------------------------------
TEST-GET-MASTER-USER in TEST-MASTER-SLAVE []:
Unexpected Error: #<UNDEFINED-FUNCTION STOP-SERVER {1024767E73}>
The function S-SYSDEPS::STOP-SERVER is undefined..
--------------------------------
I am using SBCL 2.1.2 on Linux.
Thanks.
The symbol package prefix can get really verbose at times, it'd be nice to have an option to omit it.
For instance
(export '*local*)
(defvar *local-package* nil
"If `*local-package*' designates a package instance, don't print the package
prefix of its symbols.")
(defun print-symbol (symbol stream)
(let ((package (symbol-package symbol))
(name (prin1-to-string symbol)))
(cond ((eq package +cl-package+) (write-string "CL:" stream))
((eq package +keyword-package+) (write-char #\: stream))
((eq package *local-package*)
;; Don't print the package prefix.
nil)
(package (s-xml:print-string-xml (package-name package) stream)
(write-string "::" stream))
(t (write-string "#:" stream)))
(if (char= (char name (1- (length name))) #\|)
(write-string name stream :start (position #\| name))
(write-string name stream :start (1+ (or (position #\: name :from-end t) -1))))))
The latest SBCL breaks the build on this line.
Also, check if any other accessors have to be exported.
Working on Next I have to deal with many structure / class slots whose values are function names (e.g. #'format
) since they are configuration variables set by the user.
It'd be nice to be able to serialize those functions in the #'
printed representation.
The problem is that the user could technically also specify a lambda, which is not serializable (unless we try really hard, but let's skip that).
So what about adding support for named functions?
Here is an example for s-exp serialization:
(defmethod serialize-sexp-internal ((object function) stream serialization-state)
"Serialize function OBJECT.
If the function is named FOO, serialized is to \"#'FOO\".
Note: Function serialization is not part of the original cl-prevalence."
(declare (ignore serialization-state))
(let ((function-symbol (nth-value 2 (function-lambda-expression object))))
(unless (symbolp function-symbol)
(error "Cannot serialize anonymous functions (lambdas)"))
(write-string "(:FUNCTION . " stream)
(print-symbol function-symbol stream)
(write-string ")" stream)))
Then at the end of deserialize-sexp-internal
:
(:function (symbol-function (rest sexp)))
Thoughts?
Currently, structures with custom constructors, e.g.
(defstruct (uri (:constructor %make-uri))
scheme
userinfo
host
port
path
query
fragment)
fail to deserialize because deserialize-sexp-internal
tries to call make-uri
which does not exist.
Instead, I suggest to:
(concatenate 'string "MAKE-" (symbol-name class))
exists.make-instance
instead.Thoughts?
Running tests leaves directories lying around in /tmp owned by the user running the test, which makes it impossible for any other user on the same system to run the tests:
$ ls -ld /tmp/*prevalence*
drwxr-xr-x 3 _nixbld1 wheel 96 Sep 30 22:46 /tmp/master-test-prevalence-system
drwxr-xr-x 3 _nixbld1 wheel 96 Sep 30 22:46 /tmp/slave-test-prevalence-system
drwxr-xr-x 5 _nixbld1 wheel 160 Sep 30 22:46 /tmp/test-managed-prevalence-system
This is particularly apparent with Nix, which uses a daemon with special dedicated system users for building & testing.
Instead of outputting everything on one line, it's be nice to leave some customization options to the users so that they can decide when to insert line breaks.
For instance:
(export '*one-element-per-line*)
(defvar *one-element-per-line* nil
"If non-nil, print one element per line in sequence types.")
(defun maybe-newline (stream)
(when *one-element-per-line*
(write-char #\newline stream)))
(defmethod serialize-sexp-internal ((object sequence) stream serialization-state)
"Like the original `serialize-sexp-internal' but uses `*one-element-per-line* to "
(flet ((proper-sequence (length)
(let ((id (set-known-object serialization-state object)))
(write-string "(:SEQUENCE " stream)
(prin1 id stream)
(write-string " :CLASS " stream)
(print-symbol (etypecase object (list 'list) (vector 'vector)) stream)
(write-string " :SIZE " stream)
(prin1 length stream)
(unless (zerop length)
(write-string " :ELEMENTS (" stream)
(maybe-newline stream)
(map nil
#'(lambda (element)
(write-string " " stream)
(serialize-sexp-internal element stream serialization-state)
(maybe-newline stream))
object))
(write-string " ) )" stream)))
(improper-list ()
(let ((id (set-known-object serialization-state object)))
(write-string "(:CONS " stream)
(prin1 id stream)
(write-char #\Space stream)
(serialize-sexp-internal (car object) stream serialization-state)
(write-char #\Space stream)
(serialize-sexp-internal (cdr object) stream serialization-state)
(write-string " ) " stream))))
(let ((id (known-object-id serialization-state object)))
(if id
(progn
(write-string "(:REF . " stream)
(prin1 id stream)
(write-string ")" stream))
(multiple-value-bind (seq-type length) (sequence-type-and-length object)
(ecase seq-type
((:proper-sequence :proper-list) (proper-sequence length))
((:dotted-list :circular-list) (improper-list))))))))
The above function is like the original except for the maybe-newline
calls.
Currently we can customize how a specific class instance is serialized. The default function does a good job.
However the API is very impractical for cases where I want to customize a specific slot serialization and use the default serialization for the rest of the slots.
Suggested fix: add a new method for an extra level of indirection. Example:
;; The new _exported_ method, defaults to calling the original behaviour.
(defmethod serialize-sexp-slot ((object standard-object) slot-name stream serialization-state)
(s-serialization::serialize-sexp-internal (slot-value object slot-name)
stream serialization-state))
; Existing function, tweaked to use the new method.
(defmethod serialize-sexp-internal ((object standard-object) stream serialization-state)
"Hack of `s-serialization::serialize-sexp-internal' to allow for extensible slot serialization."
(let ((id (s-serialization::known-object-id serialization-state object)))
(if id
(progn
(write-string "(:REF . " stream)
(prin1 id stream)
(write-string ")" stream))
(let ((serializable-slots (s-serialization::get-serializable-slots serialization-state object)))
(setf id (s-serialization::set-known-object serialization-state object))
(write-string "(:OBJECT " stream)
(prin1 id stream)
(write-string " :CLASS " stream)
(s-serialization::print-symbol (class-name (class-of object)) stream)
(when serializable-slots
(princ " :SLOTS (" stream)
(loop :for slot :in serializable-slots
:do (when (slot-boundp object slot)
(write-string " (" stream)
(s-serialization::print-symbol slot stream)
(write-string " . " stream)
(serialize-sexp-slot object slot stream serialization-state)
(write-string ")" stream))))
(write-string " ) )" stream)))))
;; Example customization on the user's side:
(defmethod serialize-sexp-slot ((my-object my-object-class) (slot (eql 'foo-slot)) stream serialization-sexp-slot)
(if slot ...))
Thoughts? Should I send a patch?
It looks like s-exp serialization chokes on pathnames. This simple method fixes it:
(defmethod serialize-sexp-internal ((object pathname) stream serialization-state)
"Serialize pathname OBJECT to it's printed representation starting with #P.
Note: Function serialization is not part of the original cl-prevalence."
(declare (ignore serialization-state))
(prin1 object stream))
Thoughts?
https://github.com/metawilm/cl-custom-hash-table provides us with a portable way to define custom hash tables.
These are still of the hash-table
type and thus are serialized by prevalence like any other hash table, but with the test
set to the custom test.
The new hash-function
, however, is not serialized.
This causes problems on deserialization because the custom test alone is not enough to make the custom hash table: the hash function must be provided.
Otherwise, the following condition is raised:
Unknown :TEST for MAKE-HASH-TABLE: MY-TEST-FUNCTION
One way to work around this would be to serialize the hash-function name. Then, to deserialize it, the library would use cl-custom-hash-table.
The problem is that I can't find a way to access the hash-function used for a hash-table value. Any idea?
The tests assume order of execution, because some of them set up things like test-system and other tests use it. But Fiveam does not execute the tests in a specific order, unless there are dependencies that define the order.
Fiveam does loop for the hash table in the suite, so the order execution depends on how hash-table are implemented, and at least in LispWorks that means the order is undefined and can change whenever the hash table is rehashed.
Much of the serialization functions output hard-coded strings such as "(:SEQUENCE ", etc.
When *print-case*
is set to :downcase
or :capitalize
, the result is a mix of difference cases.
It would be nice if all hard-coded strings would be cased according to *print-case*
.
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.