Common Lisp: how to override slot accessors? - overriding

I'd like to control the way the values are saved in slots and what is returned when I read a slot. Here is my class definition:
(defclass object ()
((name :accessor name-access
:initform 'noname
:initarg :name)
(value :accessor value-access
:initform 10
:initarg :value)))
I create the object this way:
(setf obj1 (make-instance 'object))
This is the way how I get the value of the slot name:
(name-access obj1)
And how I set a new value:
(setf (name-access obj1) 'realname)
What is the right way to override this accessor function (or method) in order to be able to make some changes to the object (on write) and to control the returned value?
Thank you.

You can just manually define the methods for getting and setting the slots:
(defclass foo ()
((name :initform 'noname
:initarg :name)))
(defgeneric name-access (foo)
(:method ((foo foo))
(format t "~&Getting name.~%")
(slot-value foo 'name)))
(defgeneric (setf name-access) (name foo)
(:method (name (foo foo))
(format t "~&Setting a new name.~%")
(setf (slot-value foo 'name) name)))
(defparameter *foo* (make-instance 'foo))
(name-access *foo*)
; Getting name.
;=> NONAME
(setf (name-access *foo*) 'some-name)
; Setting a new name.
;=> SOME-NAME
(name-access *foo*)
; Getting name.
;=> SOME-NAME
The book Practical Common Lisp goes through these in chapter 17. You should read that.

You can extend the accessor methods defined by DEFCLASS:
CL-USER 66 > (defclass object ()
((name :accessor name-access
:initform 'noname
:initarg :name)
(value :accessor value-access
:initform 10
:initarg :value)))
#<STANDARD-CLASS OBJECT 4220014953>
Writing, using a :before method:
CL-USER 67 > (defmethod (setf name-access) :before (new-value (o1 object))
(print "hi"))
#<STANDARD-METHOD (SETF NAME-ACCESS) (:BEFORE) (T OBJECT) 40202283BB>
Reading, with an :around method:
CL-USER 68 > (defmethod name-access :around ((o1 object))
(let ((name (call-next-method)))
(values name (length (symbol-name name)))))
#<STANDARD-METHOD NAME-ACCESS (:AROUND) (OBJECT) 4020061213>
Example:
CL-USER 69 > (let ((o1 (make-instance 'object)))
(setf (name-access o1) 'foobar)
(name-access o1))
"hi" ; side effect
FOOBAR ; return value 1
6 ; return value 2

Related

print-method function behaves weirdly

I came across some strange behaviour when trying to customize the print-object function of a CLOS object. The function does generate the intended string, but it appears outside the object definition (i.e. <OBJECT-NAME > followed by the string I wanted after the > character). The skeleton code below reproduces the issue:
(defclass object () ;;; Define some object...
((element-count
:initarg :element-count
:accessor n)
(first-element
:initform nil
:accessor 1st)
(last-element
:initform nil
:accessor end)))
(defmethod print-object ((obj object) stream) ;;; ...and then its print-object method
(print-unreadable-object (obj stream :type t))
(with-accessors ((first 1st)
(last end)
(n n))
obj
(format stream " ~[empty~:;:elements ~:*~d :content ~:*(~[~;~a~;~a ~a~:;~a ... ~a~])~]"
n first last)))
The output strings appear thus:
(defvar o1 (make-instance 'object :element-count 0)) => #<OBJECT > empty
(defvar o2 (make-instance 'object :element-count 1)) => #<OBJECT > :elements 1 :content (NIL)
(defvar o3 (make-instance 'object :element-count 2)) => #<OBJECT > :elements 2 :content (NIL NIL)
(defvar o4 (make-instance 'object :element-count 10)) => #<OBJECT > :elements 10 :content (NIL ... NIL)
I don't understand this output. Per the docs, printing outside the space shouldn't ever happen. Or should it? Well, over to you! By the way, I'm using SBCL on Portacle in Windows.
You misplaced parens - print-unreadable-object creates an environment which should encompass the whole print-object body:
(defclass airplane () ((tail-number :initarg tail :accessor plane-tail)))
(defmethod print-object ((plane airplane) stream)
(print-unreadable-object (plane stream :type t)
(princ (plane-tail plane) stream)))
(make-instance 'airplane 'tail 1234)
==> #<AIRPLANE 1234>

Simple OO style programming with Common Lisp

I am trying to make a 'pseudo OO system':
(defun bank-account ()
(let ((balance))
(labels ((init (x)
(setf balance x))
(increment (x)
(setf balance (+ balance x)))
(get-balance ()
balance))
(lambda (func)
(case func (init #'init)
(increment #'increment)
(get-balance #'get-balance))))))
(defparameter bank-account-object (bank-account))
(funcall (funcall bank-account-object 'init) 42)
(funcall (funcall bank-account-object 'increment) 10)
(funcall (funcall bank-account-object 'get-balance))
Q: are there better ways to accomplish the same without using CLOS, defstruct, or defmacro?
The problem that I see with this is that it is closed for extension, and I see no simple way to add extensibility.
Minor nitpick: that's not a bank-system but a bank-account. When you think about that further, it seems to me that the interesting part about this example domain has not been touched: double accounting, i. e. ensuring the null-sum invariant.
There are two sayings: a closure is a poor man's object, and an object is a poor man's closure. I have the feeling that you are more in the realm of the former here. However, it might be a good learning experience to think about this—as long as you don't put it into production somewhere…
;; The "class"
(defun create-bank-account ()
(let ((balance))
(labels ((init (x)
(setf balance x))
(increment (x)
(setf balance (+ balance x)))
(get-balance ()
balance))
(lambda (func)
(case func (init #'init)
(increment #'increment)
(get-balance #'get-balance))))))
;; The "methods"
(defun init-balance (object amount)
(funcall (funcall object 'init) amount))
(defun increment-balance (object amount)
(funcall (funcall object 'increment) amount))
(defun get-balance (object)
(funcall (funcall object 'get-balance)))
;; Example usage
(defparameter bank-account (create-bank-account))
(init-balance bank-account 42) ; => 42
(increment-balance bank-account 10) ; => 52
(get-balance bank-account) ; => 52
As mentioned in other answers, the resulting object might be hard to extend. That could be a feature, but one possible way to improve on it is to let it be redefined dynamically. You can even switch from classes to protoypes.
(ql:quickload :optima)
(defpackage :obj (:use :cl :optima))
(in-package :obj)
(defun make-object (&optional prototype)
(let ((properties (make-hash-table :test #'eq))
(self))
(flet ((resolve (key)
(or (gethash key properties)
(and prototype (funcall prototype :get key)))))
(setf self
(lambda (&rest args)
(optima:ematch args
((list :get :prototype) prototype)
((list :get key) (resolve key))
((list :set :prototype p)
(cerror "Continue" "Changing prototype object, are you sure?")
(setf prototype p))
((list :set key value)
(if value
(setf (gethash key properties) value)
(remhash key properties)))
((list :invoke method args)
(let ((resolved (resolve method)))
(if resolved
(apply resolved self args)
(funcall (or (resolve :no-such-method)
(error "No such method: ~a in ~a"
method
self))
self
method))))))))))
Some helper symbols:
;; call built-in command
(defmacro $ (obj method &rest args)
`(funcall ,obj ,method ,#args))
;; access property
(declaim (inline # (setf #)))
(defun # (o k) ($ o :get k))
(defun (setf #) (v o k) ($ o :set k v))
;; invoke method
(defun % (o m &rest a)
($ o :invoke m a))
A simple test
(let ((a (make-object)))
;; set name property
(setf (# a :name) "a")
;; inherit
(let ((b (make-object a)))
(print (list (# b :name)
;; shadow name property
(setf (# b :name) "b")
(# a :name)))
;; define a method
(setf (# a :foo) (lambda (self) (print "FOO")))
;; invoke it
(% a :foo)))
Bank account
(defun create-bank-account (&optional parent)
(let ((account (make-object parent)))
(prog1 account
(setf (# account :init)
(lambda (self x)
(setf (# self :balance) x)))
(setf (# account :increment)
(lambda (self increment)
(incf (# self :balance) increment))))))
(let ((account (create-bank-account)))
(% account :init 0)
(% account :increment 100)
(# account :balance))
100

Qt (via Common Lisp's qtools): QLineEdit does not activate on click but receives focus on TAB

Problem
I've run into rather weird problem: QLineEdit objects in the interface cannot be accessed by mouse clicking on them, but using Tab's they receive the focus and respond to keyboard input. But even when they have the focus, they do not respond to clicks. What makes things weirder is that the last added QLineEdit does respond to clicks.
The extra problem: mouse-inaccessible line-edits do not show tool-tips.
I am using Common Lisp's qtools to construct the interface, so I will have to do some explaining how it works. In short, I'm adding line-edits one-by-one in the loop, all of them created in the same manner and added to QGridLayout.
Updated: See below for a possible source of the problem
Parameter widget
Parameter widget is used to represent one parameter input. Each parameter has a name, value and units (of measure). The name and units are shown as labels, the value is editable and is represented by QLineEdit
(define-widget parameter-widget (QWidget)
((parameter :initarg :parameter)))
(define-subwidget (parameter-widget label) (q+:make-qlabel parameter-widget)
(setf (q+:text label) (parameter-base-name parameter)))
(define-subwidget (parameter-widget entry) (q+:make-qlineedit parameter-widget)
(setf (q+:alignment entry) +align-right+)
(setf (q+:text entry) (format nil "~A" (parameter-value parameter)))
(setf (q+:tool-tip entry) (parameter-base-description parameter)))
(define-subwidget (parameter-widget units) (q+:make-qlabel parameter-widget)
(setf (q+:text units) (parameter-units parameter)))
To indicate that parameter value has been changed, parameter-widget will emmit the new signal parameter-changed (it is translated to a signal "parameterChanged" for Qt):
(define-signal (parameter-widget parameter-changed) ())
The slot for the line edit tries to convert the text to a number, and if successful, updates the underlying parameter and emits parameter-changed:
(define-slot (parameter-widget parameter-changed) ((new-text string))
(declare (connected entry (text-changed string)))
(handler-case
(let ((new-number (parse-number new-text)))
(setf (parameter-value parameter) new-number)
(signal! parameter-widget (parameter-changed)))
(error nil)))
This method is just to automatically construct the widget for the object of type parameter (factory method):
(defmethod make-parameter-ui ((object parameter))
(make-instance 'parameter-widget :parameter object))
This method is required to align labels for multiple single parameters in parameter-container (see further-below):
(defmethod add-to-grid ((widget parameter-widget) grid row column)
(with-slots (label entry units) widget
(q+:add-widget grid label row column 1 1)
(q+:add-widget grid entry row (1+ column) 1 1)
(q+:add-widget grid units row (+ column 2) 1 1)))
Parameter container
So, if I use parameter-widget on its own - everything is OK. But most of the time I need multiple parameters in the form of parameter-container:
(define-widget parameter-container-widget (QWidget)
((parameter-container :initarg :parameter-container)))
This slot captures the signal parameter-changed from all children parameter's and re-emits it for the container
(define-slot (parameter-container-widget parameter-changed) ()
(format t "~&Re-emitting the signal...~%")
(signal! parameter-container-widget (parameter-changed)))
layout is QGridLayout to put all individual parameter-widget's for all parameter-children of parameter-container. All it does:
it loops over all individual parameters,
constructs parameter-widget for each
adds to the layout row-by-row
and connects the signal parameter-changed to the above-defined slot.
Code:
(define-subwidget (parameter-container-widget layout)
(q+:make-qgridlayout parameter-container-widget)
(loop for p in (parameter-container-children parameter-container)
for row from 0
do (let ((parameter-widget (make-parameter-ui p)))
(setf (q+:parent parameter-widget) parameter-container-widget)
(add-to-grid parameter-widget layout row 0)
(connect! parameter-widget (parameter-changed)
parameter-container-widget
(parameter-changed)))))
This method is for uniform treatment to parameter-widget and parameter-container:
(defmethod add-to-grid ((widget parameter-container-widget) grid row column)
(q+:add-widget grid widget row column 1 1))
And generic instantiator (factory method):
(defmethod make-parameter-ui ((object parameter-container))
(make-instance 'parameter-container-widget :parameter-container object))
System information
Qt4.8, Common Lisp: SBCL 1.3.7, qtools from Quicklisp, OS: Ubuntu 16.04
Update
The same problem on Windows 10
Update 2: Full minimal example
I apologise, the code above uses many definitions from other packages: putting it all would make it really long. The smallest example boils down to this:
(ql:quickload '(:qtools :qtcore :qtgui))
(defpackage :qtexample
(:use #:cl+qt))
(in-package qtexample)
(in-readtable :qtools)
(defclass parameter ()
((name :initarg :name :accessor parameter-name)
(value :initarg :value :accessor parameter-value)
(units :initarg :units :accessor parameter-units)))
(defun parameter (name value units)
(make-instance 'parameter
:name name
:value value
:units units))
(defvar *mass* (parameter "mass" 1d0 "kg"))
(defvar *velocity* (parameter "velocity" 0.5d0 "m/s"))
(defvar *temperature* (parameter "temperature" 300d0 "K"))
(defvar *pressure* (parameter "pressure" 1d5 "Pa"))
(define-widget parameter-widget (QWidget)
((parameter
:initarg :parameter
:accessor parameter-widget-parameter)))
(define-subwidget (parameter-widget label)
(q+:make-qlabel parameter-widget)
(setf (q+:text label) (parameter-name parameter)))
(defmethod make-ui ((object parameter))
(make-instance 'parameter-widget :parameter object))
(defconstant +align-right+ 2)
(define-subwidget (parameter-widget entry)
(q+:make-qlineedit parameter-widget)
(setf (q+:alignment entry) +align-right+)
(setf (q+:text entry) (format nil "~A" (parameter-value parameter))))
(define-subwidget (parameter-widget units)
(q+:make-qlabel parameter-widget)
(setf (q+:text units) (parameter-units parameter)))
(define-signal (parameter-widget parameter-changed) ())
(define-slot (parameter-widget entry) ((new-text string))
(declare (connected entry (text-changed string)))
(format t "~&Parameter has changed~%")
(handler-case
(let ((new-number (parse-number:parse-number new-text)))
(setf (parameter-value parameter) new-number)
(signal! parameter-widget (parameter-changed)))
(error nil)))
(defmethod add-to-grid ((widget parameter-widget) grid row column)
(with-slots (label entry units) widget
(q+:add-widget grid label row column 1 1)
(q+:add-widget grid entry row (1+ column) 1 1)
(q+:add-widget grid units row (+ column 2) 1 1)
(list (1+ row) (+ column 3))))
(define-widget parameter-widget-window (QWidget)
((parameter :initarg :parameter)))
(define-subwidget (parameter-widget-window parameter-widget)
(make-ui parameter))
(define-subwidget (parameter-widget-window grid)
(q+:make-qgridlayout parameter-widget-window)
(add-to-grid parameter-widget grid 0 0))
(defun parameter-example (parameter)
(with-main-window
(window (make-instance 'parameter-widget-window
:parameter parameter))))
(define-widget parameter-container-widget (QWidget)
((parameter-container
:initarg :parameter-container
:accessor parameter-container-widget-parameter-container)))
(defmethod make-ui ((object list))
(make-instance 'parameter-container-widget :parameter-container object))
(define-slot (parameter-container-widget parameter-changed) ()
(format t "~&Re-emitting the signal...~%")
(signal! parameter-container-widget (parameter-changed)))
(define-subwidget (parameter-container-widget layout)
(q+:make-qgridlayout parameter-container-widget)
(let* ((parameter-widgets (loop for p in parameter-container
collect (make-ui p))))
(loop for p in parameter-widgets
for row from 0
do (progn
(setf (q+:parent p) parameter-container-widget)
(add-to-grid p layout row 0)
(connect! p
(parameter-changed)
parameter-container-widget
(parameter-changed))))))
(define-widget parameter-container-widget-window (QWidget)
((parameter-container :initarg :parameter-container)))
(define-subwidget (parameter-container-widget-window container-widget)
(make-ui parameter-container)
(setf (q+:parent container-widget) parameter-container-widget-window))
(define-slot (parameter-container-widget-window parameter-changed) ()
(declare (connected container-widget (parameter-changed)))
(format t "~&Got parameter changed~%"))
(defmethod add-to-grid ((widget parameter-container-widget) grid row column)
(q+:add-widget grid widget row column))
(defun example-parameter-container (parameter-container)
(with-main-window
(window (make-instance 'parameter-container-widget-window
:parameter-container parameter-container))))
;; to run:
(example-parameter-container (list *mass* *velocity*))
While working on it, I stumbled upon a possible solution. This line
(setf (q+:parent p) parameter-container-widget)
sets the parent for a sub-widget p (in the list of sub-widgets) to be parameter-container-widget. If this line is commented, everything works fine.
p's sub-widgets (which include entry, an instance of QLineEdit) are later added into the grid, but not p itself! In a way, parameter-widget is not a proper widget: it's just a collection of other widgets with the rules of how to add them into the container. But it needs to act as widget in a sense of being able to receive and send signals.
After #KubaOber and #Shinmera suggestions I managed to fix the problem. I'm posting here the fix for the future reference.
Preliminaries didn't change (except, I forgot to add :PARSE-NUMBER system):
(ql:quickload '(:qtools :qtcore :qtgui :parse-number))
(defpackage :qtexample
(:use #:cl+qt))
(in-package qtexample)
(in-readtable :qtools)
(defclass parameter ()
((name :initarg :name :accessor parameter-name)
(value :initarg :value :accessor parameter-value)
(units :initarg :units :accessor parameter-units)))
(defun parameter (name value units)
(make-instance 'parameter
:name name
:value value
:units units))
(defvar *mass* (parameter "mass" 1d0 "kg"))
(defvar *velocity* (parameter "velocity" 0.5d0 "m/s"))
(defvar *temperature* (parameter "temperature" 300d0 "K"))
(defvar *pressure* (parameter "pressure" 1d5 "Pa"))
Since PARAMETER-WIDGET is not really a widget, but just a container for other widgets (and by itself it cannot be added into a proper widget-container - otherwise the alignment of labels will go off - see ADD-TO-GRID method) but it needs to be able to receive and send signals, it is inherited from QObject rather than QWidget. All sub-widgets now are just normal class-slots in it instead of being defined by (DEFINE-SUBWIDGET ...). Notice, no parent was supplied for any sub-widget: parent property will be assigned when these widgets are added to a container-widget.
(define-widget parameter-widget (QObject)
((parameter
:initarg :parameter
:accessor parameter-widget-parameter)
(label :initform (q+:make-qlabel))
(entry :initform (q+:make-qlineedit))
(units :initform (q+:make-qlabel))))
Initialization goes into INITIALIZE-INSTANCE :AFTER method:
(defconstant +align-right+ 2)
(defmethod initialize-instance :after ((object parameter-widget) &key)
(with-slots (parameter label entry units) object
(setf (q+:text label) (parameter-name parameter))
(setf (q+:text entry) (format nil "~A" (parameter-value parameter)))
(setf (q+:alignment entry) +align-right+)
(setf (q+:text units) (parameter-units parameter))))
The rest of definition stays the same (signalling is mostly irrelevant to the question but helps to understand why I am jumping through all these hoops):
(defmethod make-ui ((object parameter))
(make-instance 'parameter-widget :parameter object))
(define-signal (parameter-widget parameter-changed) ())
(define-slot (parameter-widget entry) ((new-text string))
(declare (connected entry (text-changed string)))
(format t "~&Parameter has changed~%")
(handler-case
(let ((new-number (parse-number:parse-number new-text)))
(setf (parameter-value parameter) new-number)
(signal! parameter-widget (parameter-changed)))
(error nil)))
(defmethod add-to-grid ((widget parameter-widget) grid row column)
(with-slots (label entry units) widget
(q+:add-widget grid label row column 1 1)
(q+:add-widget grid entry row (1+ column) 1 1)
(q+:add-widget grid units row (+ column 2) 1 1)
(list (1+ row) (+ column 3))))
And this is a quick demo that everything works for a single parameter. Now, PARAMETER-WIDGET is no longer a widget, so it is added as a class-slot.
(define-widget parameter-widget-window (QWidget)
((parameter :initarg :parameter)
(parameter-widget)))
The grid of the window:
(define-subwidget (parameter-widget-window grid)
(q+:make-qgridlayout parameter-widget-window))
Here the addition of PARAMETER-WIDGET components into the grid was moved out of this definition. The reason: slot PARAMETER-WIDGET at this point is unbound. It does get bound in INITIALIZE-INSTANCE :AFTER method and where all components are added to the grid:
(defmethod initialize-instance :after ((object parameter-widget-window) &key)
(with-slots (parameter parameter-widget grid) object
(setf parameter-widget (make-ui parameter))
(setf (q+:parent parameter-widget) object)
(add-to-grid parameter-widget grid 0 0)))
And the launcher stays the same:
(defun parameter-example (parameter)
(with-main-window
(window (make-instance 'parameter-widget-window
:parameter parameter))))
To run: (parameter-example *mass*)
PARAMETER-CONTAINER-WIDGET is a proper widget. Its definition didn't change:
(define-widget parameter-container-widget (QWidget)
((parameter-container
:initarg :parameter-container
:accessor parameter-container-widget-parameter-container)))
(defmethod make-ui ((object list))
(make-instance 'parameter-container-widget :parameter-container object))
(define-slot (parameter-container-widget parameter-changed) ()
(format t "~&Re-emitting the signal...~%")
(signal! parameter-container-widget (parameter-changed)))
And LAYOUT definition doesn't change either. But now it is safe to set the parent property of p (PARAMETER-WIDGET) to PARAMETER-WIDGET-CONTAINER, so it is get destroyed when the container is destroyed.
(define-subwidget (parameter-container-widget layout)
(q+:make-qgridlayout parameter-container-widget)
(let* ((parameter-widgets (loop for p in parameter-container
collect (make-ui p))))
(loop for p in parameter-widgets
for row from 0
do (progn
(add-to-grid p layout row 0)
(let ((pp p))
(setf (q+:parent pp) parameter-container-widget))
(connect! p
(parameter-changed)
parameter-container-widget
(parameter-changed))))))
Adding to grid this widget is trivial (yet not completely correct, but fixable, see further-below):
(defmethod add-to-grid ((widget parameter-container-widget) grid row column)
(q+:add-widget grid widget row column))
The demonstration part didn't change:
(define-widget parameter-container-widget-window (QWidget)
((parameter-container :initarg :parameter-container)))
(define-subwidget (parameter-container-widget-window container-widget)
(make-ui parameter-container)
(setf (q+:parent container-widget) parameter-container-widget-window))
(define-slot (parameter-container-widget-window parameter-changed) ()
(declare (connected container-widget (parameter-changed)))
(format t "~&Got parameter changed~%"))
(defun example-parameter-container (parameter-container)
(with-main-window
(window (make-instance 'parameter-container-widget-window
:parameter-container parameter-container))))
To run: (example-parameter-container (list *mass* *velociy*))
It can also handle hierarchical parameters like so
(example-parameter-container (list *mass* *velocity* (list *temperature* *pressure*)))
And this run will show why ADD-TO-GRID for PARAMETER-CONTAINER-WIDGET needs to be a bit more complex, but this is a different story.

How do I mem-aref the output of a meta-object in CFFI

I have this function scalar which is a wrapper of the 2 function definitions commented above it.
My ? is how do I mem-aref the output of (scalar 1 2 3 4), which is #<CV-SCALAR {10044559D3}>
I think #<CV-SCALAR {10044559D3}> is called a Meta-Object
;; Scalar* cv_create_Scalar(double val0, (double val1, double val2, double val3)
(defcfun ("cv_create_Scalar" %scalar) scalar
(val0 :double)
(val1 :double)
(val2 :double)
(val3 :double))
(define-foreign-type scalar ()
((garbage-collect :reader garbage-collect :initform nil :initarg
:garbage-collect))
(:actual-type :pointer)
(:simple-parser scalar))
(defclass cv-scalar ()
((c-pointer :reader c-pointer :initarg :c-pointer)))
(defmethod translate-to-foreign ((lisp-value cv-scalar) (c-type scalar))
(c-pointer lisp-value))
(defmethod translate-from-foreign (c-pointer (c-type scalar))
(let ((scalar (make-instance 'cv-scalar :c-pointer c-pointer)))
(when (garbage-collect c-type)
(tg:finalize scalar (lambda () (del-scalar c-pointer))))
scalar))
If you defclass and defmethods are defined as above you run (mem-aref (c-pointer a) :int 1) to mem-aref the return-value

How to make function using class (Common Lisp)

I need to make a function make-numbers which make an instance of class numbers:
(defclass numbers ()
((x :initform 0)
(y :initform 0)))
Imput should be li this:(make-numbers 2 8)
I started: (defun make-numbers (new-x new-y) (...., but I don't know how continue. I Have tried it all the day, no result. Finally, I need to count this two numbers.
Do you have any idea? Thanks.
I would suggest you add :initarg keywords for your slots:
(defclass numbers ()
((x :initform 0 :initarg :x)
(y :initform 0 :initarg :y)))
Then invoke make-instance from your function:
(defun make-numbers (new-x new-y)
(make-instance 'numbers :x new-x :y new-y))
That way, you won't have to use setf on slot-value to initialize the slots of your instance.

Resources