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

Function and member generators #26

Open
mmontone opened this issue Sep 10, 2023 · 0 comments
Open

Function and member generators #26

mmontone opened this issue Sep 10, 2023 · 0 comments

Comments

@mmontone
Copy link

mmontone commented Sep 10, 2023

Hi.

Thanks for writing this nice library. I'm using it to generate random data from schemas: https://mmontone.github.io/schemata/#Data-generation

I'm missing some generators, and I thought I'd share my views.

One, the possibility of lifting a function (including a lambda) as generator.

https://github.com/mmontone/schemata/blob/3ed6f36cbc227ccf69bb0d62d3037ed325d7a2ed/generators.lisp#L16C1-L30

This is my current implementation:

 (defclass func (check-it::custom-generator)
    ((check-it::bias :initform 1.0
                     :accessor check-it::bias
                     :allocation :class)
     (func :initarg :func)))
  (setf (get 'func 'check-it::genex-type) 'generator)
  (setf (get 'func 'check-it::generator-form)
        `(lambda ,'(func) (make-instance ','func ,@'(:func func))))

  (defmethod generate ((generator func))
    (let ((func (slot-value generator 'func)))
      (funcall func)))
  )

and this is how you can use: (generator (func (lambda () (1+ (random 100))))).

I find this generator extremely valuable as it lets me plug arbitrary in-line functions that return random data easily.

This implementation doesn't work because it caches the result:

(def-generator func (func)
  (generator (funcall func)))

But this alternative implementation does work, and is simpler and more direct:

(defmethod check-it::generate ((generator function))
  (funcall generator))

The other generator, is a "member-of" generator, that chooses a random element from a collection (list, hash-table, or other).

This is my current implementation:

https://github.com/mmontone/schemata/blob/3ed6f36cbc227ccf69bb0d62d3037ed325d7a2ed/generators.lisp#L37-L48

I'm using that one quite a lot of too.

I'm using like:

(defparameter *person-names*
  (list "John" "Peter" "Stan" "Steve" "Wendy" "Caroline"))

(def-generator person-name-generator ()
  (generator (member-of *person-names*)))

(def-generator age-generator ()
  (generator (func (lambda () (1+ (random 100))))))

(defschema person
    (object person
            ((name string :generator (generator (person-name-generator)))
             (age integer :required nil
                          :generator (generator (age-generator))))))

So, it would be nice that some implementation of these generators be included as part of check-it, in my opinion.

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

No branches or pull requests

1 participant