.gitignore | ||
LICENSE | ||
objective-lisp.asd | ||
objective-lisp.lisp | ||
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.