cl-defstruct macro does preserve enough info to make such a function possible, but I don't think anyone has written such a beast yet.
The way this info is stored has changed in Emacs-25: now the macro expands to various other things plus a call to
cl-struct-define which creates a class object (itself a struct). You can inspect it with
C-h o cl-structure-class RET (which is the corresponding metaclass) and
C-h o cl-slot-descriptor RET. And you can get the class object from the type name with
You should even be able to extend
make-instance with a method to handle defstruct types. E.g.:
(cl-defmethod make-instance ((class symbol) &rest slots)
(let ((co (cl--find-class class)))
(if co (apply #'make-instance co slots)
(cl-defmethod make-instance ((sc cl-structure-class) &rest slots)
(let* ((sds (cl--struct-class-slots sc))
;; For techno-historical reasons, the first slot should be the
;; type/symbol rather than the class.
(o (make-record (cl--struct-class-name sc) (length sds) nil))
(push (cons (intern (substring (symbol-name (pop slots)) 1))
(dotimes (i (length sds))
(pcase-let* (((cl-struct cl-slot-descriptor name initform)
(aref sds i)))
(aset o (1+ i) (or (alist-get name alist) initform))))
Note: currently in Elisp,
apply can be a performance problem (e.g. it's the main bottleneck in
cl-print-object), so the above could be too slow for some use-cses.