Syntactic sugar for object-oriented Lisp.
Go to file
~keith d02322ce73
Slight improvement for slot accessors
2021-11-16 16:57:40 +00:00
.gitignore Initial commit 2021-11-14 04:13:48 +00:00
LICENSE Initial commit 2021-11-14 04:13:48 +00:00
README.md Slight improvement for slot accessors 2021-11-16 16:57:40 +00:00
objective-lisp.asd objective-lisp 1.0 2021-11-14 05:22:10 +00:00
objective-lisp.lisp Slight improvement for slot accessors 2021-11-16 16:57:40 +00:00

README.md

objective-lisp

Syntactic sugar for object-oriented Lisp.

objective-lisp provides a simple, concise, and (slightly) more conventional syntax for accessing the slots and methods of objects. It defines a reader macro for the [ and ] characters (although you can change these in the code).

Usage

TL;DR: [object slot-name] is like object.slotName in C++, and [object (.method args)] is like object.method(args) in C++.

First, to enable objective-lisp's syntax, just load the system:

(asdf:load-system 'objective-lisp)

objective-lisp's syntax takes the form of a special S-expression, contained in square brackets rather than parentheses. Each form within treats the previous form as its subject, like a chain of . (dot) operators in C-like languages.

[foo bar baz quux]
;; C++: foo.bar.baz.quux

To access a slot, just put the slot name after the object:

[object slot-name]
;; => (slot-value object 'slot-name)

(setf [object slot-name] value)
;; => (setf (slot-value object 'slot-name) value)

slot-name doesn't have to be an unquoted symbol:

(defun choose-slot (x)
	(if (<= x 0) 'pos-slot 'neg-slot))
(setf [object (choose-slot -1)] value)

(defvar slot-var 'slot-name)
(setf [object `,slot-var] value)

To call a method, write an S-expression as you normally would, but put a . (dot) before its name:

[object (.method arg-1 arg-2 ... arg-N)]
;; => (method object arg-1 arg-2 ... arg-N)

Under the hood, this just passes object as the first argument to method, so you can do stuff like this (I won't kinkshame you, but your coworkers might):

[object slot-name (.setf value)]
;; => [(slot-value object 'slot-name) (.setf value)]
;;  => (setf (slot-value object 'slot-name) value)

And, of course, you can chain multiple slot accesses and method calls together:

[object child (.method-of-child) (.method-of-return-value) slot-of-return-value]
;; => [(slot-value object 'child) (.method-of-child) ...]
;;  => [(method-of-child (slot-value object 'child)) (.method-of-return-value) ...]
;;   => [(method-of-return-value (method-of-child ...)) slot-of-return-value]
;;    => (slot-value (method-of-return-value ...) 'slot-of-return-value)

NEW: You can also call slot accessors without wrapping them in a cons. (This works for any method that takes no additional arguments, but that might cause code readability issues.)

[object .slot-accessor]
;; => (slot-accessor object)

License

objective-lisp is public domain. You can do whatever you want with it. I don't really care about credit, it's just a silly little thing I wrote in a few hours.

But if you find it useful, please let me know. I'd love to hear about it.