Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Objective-CL: Objective-C­like syntax for Common Lisp

266 views
Skip to first unread message

Pascal J. Bourguignon

unread,
Dec 22, 2010, 10:29:36 AM12/22/10
to

I've been writing a couple of reader macros to implement an
Objective-C­like syntax for Common Lisp, above the ccl Objective-C
bridge. (But eventually, it should work with any implementation
providing an Objective-C FFI).

I still have finalize the processing of type specifiers (I need to learn
more about ccl FFI types), however here is already the documentation
source.

You may find a snapshot tarball at
ftp://ftp.informatimago.com/users/pjb/lisp/objcl.tar.bz2
with the sources and the PDF of the documentation.

I'd gladly read any comment about it.

------------------------------------------------------------------------
.. comment: -*- mode:rst; coding:utf-8; -*-

Objective-CL
############

Objective-C­like syntax for Common Lisp
=======================================

Bugs
----

The ``type-specifiers`` are not defined yet. I need to learn about
``ccl`` FFI and perhaps add a syntax, or at least improve the reading
of ``type-specifiers``. Notably, for now they're merely read in the
keyword package so we cannot give type specifiers such as: (NSRect) or
(NSWindow*).


Motivation
----------

The purpose of this package is to provide a few reader macros
implementing a syntax like Objective-C to program with Objective-C FFI
such as the ``ccl`` Objective-C bridge.

The principles of the Objective-C syntax is that it is a small set of
extensions over the syntax of the base language (C in the case of
Objective-C). Namely:

- message sending expressions are put inside brackets (inspired from
Smalltalk block notation), and have basically the Smalltalk message
sending syntax.

- class declarations and definitions (interface and implementation)
and other Objective-C specific elements use keywords prefixed by the
#\\@ character.


The later is a little at odd with lisp nature, where every form is an
expression, and where parenthesized syntax is prefered. We will
therefore provide a more Smalltalk-like way to define classes and
methods (while retaining the #\\@ character as prefix for some
symbols, and as a reader macro to read Objective-C string literals).


Principles
----------

Two reader macros are provided:

- a reader macro bound to #\\[ is used to parse message sending
expressions, just like in Objective-C, but since the underlying
language is lisp, sub-expressions starting with parentheses are read
just like normal sexps (they may further contain Objective-CL syntax).

- a reader macro bound to #\\@ which is used to read:

- an Objective-C literal strings when followed by a double-quote
starting a lisp string.

- a class or method definition expression, when followed by an
opening bracket #\\[. The syntax used for these definition
expression is similar to the message sending syntax, but it's
processed more like a special operator or macro than a real
message sending: the sub-expression are evaluated with different
rules that depend on the operation. It's called a pseudo-message.

- a normal lisp symbol otherwise.

These reader macros expand to normal lisp forms, using symbols
exported from a portability layer package, nicknamed OCLO, which
should be implemented specifically for each Objective-C bridge or FFI.
The implementation of this bridge is out of scope of these syntax-
providing reader macros.


Message Sending
---------------

The syntax is: ::

objcl-message-expr := '[' message-send ']' .

message-send := recipient message .
recipient := sexp | class-name | 'super' | 'self' .
class-name := objcl-identifier .

message := simple-selector | compound-selector final-arguments .

simple-selector := objcl-identifier .
compound-selector := objcl-identifier ':' sexp compound-selector
| objcl-identifier ':' sexp .
final-arguments := | '(' type-identifier ')' sexp final-arguments .
type-identifier := symbol .


-- FIXME type-identifier; perhaps we need:
-- type-identifier := symbol | symbol sexp .
-- for example: (char *)cString (array (int 10))tenInts ?
-- Check with what is available at the FFI/bridge level.


An ``objcl-identifier`` is a case sensitive identifier that is converted
to a lisp symbol according to the rules of Objective-C to Common Lisp
identifier translation.

A ``sexp`` is a normal lisp expression, which might be another message
sending bracketed expression (or another Objective-CL form).

There should be no space between the ``objcl-identifier`` and the colon.
After the first ``objcl-identifier`` in a compound-selector, the
remaining ``objcl-identifiers`` can be absent, in which case the colon
must be separated from the previous expression by a space.


When recipient is ``super``, an ``(oclo:send-super self ...)`` form is returned.
FIXME document the other forms returned.

Examples: ::

[self update]

[window orderFront:sender]

[array performSelector:(@selector "drawRect:") withObject:rect]

(let ((o [[NSObject alloc] init]))
[NSArray arrayWithObjects:o (id)o (id)o (id)nil])


'[array performSelector:(@selector "drawRect:") withObject:rect]
→ (OBJC:SEND ARRAY :PERFORM-SELECTOR (@SELECTOR "drawRect:") :WITH-OBJECT RECT)

Class definition
----------------

Classes are created by sending a ``subClass:slots:`` pseudo-message to its superclass.

The syntax is : ::

objcl-definition := '@[' class-definition | instance-method-definition | class-method-definition ']' .

class-definition := super-class-name 'subClass:' class-name 'slots:' '(' slots ')' .

class-name := objcl-identifier .
super-class-name := objcl-identifier .
slots := | slot slots .
slot := lisp-slot | objcl-slot .
lisp-slot := slot-specifier . -- see clhs defclass.


-- objcl-slot := ... -- not defined yet.
-- We'd want some simplified definition, and using Obj-C names.


Examples: ::

@[NSObject subClass:SpaceShip
slots:((position :accessor ship-position :initform (make-position))
(speed :accessor ship-speed :initform 0.0))]


Method definition
-----------------

Class and instance methods are defined by sending a pseudo-message to
the class, either ``method:resultType:body:`` to create an instance
method, or ``classMethod:resultType:body:`` to create a class method.


The syntax is : ::

objcl-definition := '@[' class-definition | instance-method-definition | class-method-definition ']' .

instance-method-definition := class-name 'method:' '(' signature ')'
'resultType:' '(' type-identifier ')'
'body:' body .

class-method-definition := class-name 'classMethod:' '(' signature ')'
'resultType:' '(' type-identifier ')'
'body:' body .

class-name := objcl-identifier .
signature := simple-signature | compound-signature final-signature .
simple-signature := objcl-identifier .
compound-signature := objcl-identifier ':' '(' type-identifier ')' objcl-identifier compound-signature
| objcl-identifier ':' '(' type-identifier ')' objcl-identifier .
final-signature := '&rest' objcl-identifier .
body := | sexp body .

-- FIXME type-identifier; perhaps we need:
-- type-identifier := symbol | symbol sexp .
-- for example: (char *)cString (array (int 10))tenInts ?
-- Check with what is available at the FFI/bridge level.

There should be no space between the ``objcl-identifier`` and the colon.
After the first ``objcl-identifier`` in a compound-selector, the
remaining ``objcl-identifiers`` can be absent, in which case the colon
must be separated from the previous expression by a space.

Examples: ::

@[SpaceShip classMethod:(shipAtPosition:(Position)aPosition)
resultType:(id)
body:(let ((new-ship [[self alloc] init]))
[new-ship setPosition:aPosition]
new-ship)]

@[SpaceShip method:(moveToward:(Direction)aDirection atSpeed:(double)velocity)
resultType:(id)
body:(let ((new-pos [[self position] offset:...]))
(do-something new-pos)
[self setPosition:new-pos])]

String literals
---------------

The syntax read is: ::

objcl-string-literal := '@"' { character } '"' .

A CL string is read (ie. with the same escaping rules as normal CL
strings), and an (oclo:@ "string") form is returned.

Examples: ::

@"Untitled"
@"String with \"quotes\" and \\ backslash."
@"String with
new lines"

--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.

Matthias Benkard

unread,
Dec 23, 2010, 10:34:17 AM12/23/10
to
Hi,

The naming may be a bit unfortunate, since my own Objective-C bridge
is called the same:

http://matthias.benkard.de/objective-cl/

It even provides a similar reader syntax for message passing:
http://matthias.benkard.de/objective-cl/documentation/fun_enable-objective-c-syntax.html

That said, your syntax extension seems significantly more
comprehensive, even when reduced to just the message passing part.
Mine doesn't support type annotations, for example.

The identical naming may confuse people all the more, though. :)

Matthias

Francogrex

unread,
Dec 23, 2010, 3:24:47 PM12/23/10
to
On Dec 23, 4:34 pm, Matthias Benkard <mulkiat...@gmail.com> wrote:
> Hi,
>
> The naming may be a bit unfortunate, since my own Objective-C bridge
> is called the same:
>
> http://matthias.benkard.de/objective-cl/
> ...

It is a pity that you didn't put your efforts together and seemed to
have done the same work in parallel. Isn't there somewhere that people
can post what projects they are busy with so others can know and pool
efforts?
I have one question for both (more for pjb), it's very general: why
objective-c ? I am probably wrong but development for apple isn't so
widespread especially in europe. Mac is really not that successful
around here despite iphone and all the new apple gadgets...

markha...@gmail.com

unread,
Dec 24, 2010, 3:43:47 AM12/24/10
to
On Dec 23, 2:24 pm, Francogrex <fra...@grex.org> wrote:
> I have one question for both (more for pjb), it's very general: why
> objective-c ? I am probably wrong but development for apple isn't so
> widespread especially in europe. Mac is really not that successful
> around here despite iphone and all the new apple gadgets...

If you pay him, he'll write some code for the VIC 20, which is finding
a big resurgence in Europe.

Tim Bradshaw

unread,
Dec 24, 2010, 4:10:37 AM12/24/10
to
On 2010-12-23 20:24:47 +0000, Francogrex said:

> I have one question for both (more for pjb), it's very general: why
> objective-c ? I am probably wrong but development for apple isn't so
> widespread especially in europe. Mac is really not that successful
> around here despite iphone and all the new apple gadgets...

It's the second largest desktop/laptop platform, I think.

Frank GOENNINGER

unread,
Dec 27, 2010, 5:58:13 AM12/27/10
to
Tim Bradshaw <t...@tfeb.org> writes:

Yep. And growing very fast in the business laptop segment. We're a "All
Mac" company here. Many companies in Germany are moving away from
Microsoft due to significantly lower TCO for a Mac-based IT
infrastructure.

Cheers
Frank

Antony

unread,
Dec 27, 2010, 3:21:24 PM12/27/10
to
On 12/27/2010 2:58 AM, Frank GOENNINGER wrote:
> due to significantly lower TCO for a Mac-based IT
> infrastructure.
What are the main specific things if any? (that's a genuine question)
-Antony

Pascal J. Bourguignon

unread,
Dec 28, 2010, 9:09:08 AM12/28/10
to
Antony <remove+spam...@gmail.com> writes:

Google for: tco mac windows.

Pascal J. Bourguignon

unread,
Apr 2, 2011, 1:25:44 AM4/2/11
to
Francogrex <fra...@grex.org> writes:

> On Dec 23, 4:34 pm, Matthias Benkard <mulkiat...@gmail.com> wrote:
>> Hi,
>>
>> The naming may be a bit unfortunate, since my own Objective-C bridge
>> is called the same:
>>
>> http://matthias.benkard.de/objective-cl/
>> ...
>
> It is a pity that you didn't put your efforts together and seemed to
> have done the same work in parallel. Isn't there somewhere that people
> can post what projects they are busy with so others can know and pool
> efforts?

Well, it's not the first time that I have searched for something, not
found it, and once I wrote it myself, somebody comes with a pointer...


> I have one question for both (more for pjb), it's very general: why
> objective-c ? I am probably wrong but development for apple isn't so
> widespread especially in europe. Mac is really not that successful
> around here despite iphone and all the new apple gadgets...

First, I've been a Mac Developer since 1984, intermitently, granted, but
still. Actually, the main absence has been when I was developing on
NeXTSTEP.

Objective-C is not a bad programming language.
Basically, it's Smalltalk + C.
Compared to C, it has the advantage of being OO.
Compared to C++, well anything compared to C++ has advantages.
Sure, it's not lisp or smalltalk, but that's what OpenStep (ie. Cocoa)
is written with.

Next, I'm French. France is (or has been, I don't know the last
statistics) the biggest market for Apple outside of the USA. Gassée is
French.

Finally, I don't know anything about Microsoft operating systems.
Actually, I can't remember the last time I worked for a company who used
Microsoft operating systems (apart in the accounting department). Even
in Spain, where indeed, Microsoft takes much more space than in France,
I know only people who use only Macintosh, and companies who develop for
or use also Macintosh.


And of course, the point of developing those bridges is to develop for
MacOSX and iOS. CCL provides a lispy bridge, but I find it easier to
use Objective-C syntax to write OpenStep code, if only to copy-and-paste
examples.

0 new messages