Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Searialize lisp-file contents to read-able data? #6

Open
aartaka opened this issue Sep 6, 2022 · 7 comments
Open

Searialize lisp-file contents to read-able data? #6

aartaka opened this issue Sep 6, 2022 · 7 comments

Comments

@aartaka
Copy link
Contributor

aartaka commented Sep 6, 2022

How about this: define a reader macro for classes and (de)serialize objects with this macro in *readtable*? Something like sharpsign-s reader macro for structures, but for classes. Maybe even rebind the structure one? Then we can rebind readtables to the new syntax for the time or reading:

(defmethod files:serialize ((profile profile) (file lisp-file) stream &key)
  (let ((*readtable* (copy-readtable)))
    (set-dispatch-macro-character #\# #\S #'read-class-or-structure)
    ;; A hypothetical function writing the object with the #S syntax.
    (write-nested-maybe-objects (content file) :stream stream)))

(defmethod files:deserialize ((profile profile) (file lisp-file) stream &key)
  (declare (ignore stream))
  (let ((*readtable* (copy-readtable)))
    (set-dispatch-macro-character #\# #\S #'read-class-or-structure)
    ;; A hypothetical function writing the object with the #S syntax.
    (read (call-next-method))))

Benefits:

  • Concise (much more than cl-prevalence, I'm guessing).
  • Optimized as much as read is (a lot, I'm guessing).
  • Looks familliar.
  • No dependencies.

Downsides:

  • Non-portable.
  • Requires a custom printer (or can we somehow instrementalize Lisp printer to output the new syntax? I wouldn't be surprized if we actually can...)
@Ambrevar
Copy link
Member

Ambrevar commented Sep 7, 2022

If I get it right, you want to skip the deserialize call so that read-ing would be enough, is this correct?

In any case, we would not replace cl-prevalence, since write-nested-maybe-objects is essentially what cl-prevalence does.

Note: can we leverage make-load-form?

@aartaka
Copy link
Contributor Author

aartaka commented Sep 7, 2022

Looks interesting. You never know how much foresight you can discover in the spec ( ͡° ͜ʖ ͡°)

EDIT: an -> can

@Ambrevar
Copy link
Member

Ambrevar commented Sep 7, 2022

Actually make-load-form would only work if we load the file instead of merely read-ing it. Not sure that would fit the bill here...

@aartaka
Copy link
Contributor Author

aartaka commented Sep 7, 2022

Actually make-load-form would only work if we load the file instead of merely read-ing it. Not sure that would fit the bill here...

That's would work perfectly in conjunction with #5! Imagine: we serialize the data to a huge make-load-form output, write it to a file, complile to fasl, and then load it, getting the whole set of objects restored! \(@ ̄∇ ̄@)/

@aartaka
Copy link
Contributor Author

aartaka commented Sep 7, 2022

A small demo that seems to work on simple/standard types:

(defvar *data* nil)

(defun object->file (object file)
  (with-open-file (f file :direction :output
                          :if-does-not-exist :create
                          :if-exists :supersede)
    (prog1
        (write `(setf *data* ,(make-load-form object)) :stream f)
      ;; Optional, to speed things up.
      (compile-file file)
      file)))

(defun file->object (file)
  (load file)
  *data*)

@Ambrevar
Copy link
Member

OK, but what abou the readtable trick from the original post?

@Ambrevar
Copy link
Member

Also before working on this, let's run some benchmarks (e.g. on Nyxt's GHT).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants