<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>I guess I would like to hear more about why adding an Objective-C like syntax to Lisp is a good thing. No flame war please, I am not saying that there could be no good reason but I am not quite sold. As many of you know Lisp itself is not generally considered a great programming language from a syntactic point of view due to parenthesis paranoia. However, if I would be asked to point to one programming language disliked by todays students even more it actually would be Objective-C. BUT, the students do use Objective-C + Cocoa because they can make cool iOS apps, e.g., games they can actually make money with, IN SPITE of the Objective-C syntax not thanks to it. </div><div><br></div><div>Alex</div><div><br></div><br><div><div>On Dec 22, 2010, at 8:28 AM, Pascal J. Bourguignon wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Hello,<br><br>I've been writing a couple of reader macro to implement an<br>Objective-C­like syntax for Common Lisp, above the ccl Objective-C<br>bridge.<br><br>I still have finalize the processing of type specifiers (I need to learn<br>more about ccl FFI types), however here is already the documentation<br>source.<br><br>You may find a snapshot tarball at <br><a href="ftp://ftp.informatimago.com/users/pjb/lisp/objcl.tar.bz2">ftp://ftp.informatimago.com/users/pjb/lisp/objcl.tar.bz2</a><br>with the sources and the PDF of the documentation.<br><br><br>Eventually, it would be nice if this was distributed with ccl, as a<br>contribution (for now it's under GPL2, but I would provide any required<br>license for integration with ccl).<br><br>I'd gladly read any comment about it.<br><br>------------------------------------------------------------------------<br>.. comment: -*- mode:rst; coding:utf-8; -*-<br><br>Objective-CL<br>############<br><br>Objective-C­like syntax for Common Lisp<br>=======================================<br><br>Bugs<br>----<br><br>The ``type-specifiers`` are not defined yet.  I need to learn about<br>``ccl`` FFI and perhaps add a syntax, or at least improve the reading<br>of ``type-specifiers``.  Notably, for now they're merely read in the<br>keyword package so we cannot give type specifiers such as: (NSRect) or<br>(NSWindow*).<br><br><br>Motivation<br>----------<br><br>The purpose of this package is to provide a few reader macros<br>implementing a syntax like Objective-C to program with Objective-C FFI<br>such as the ``ccl`` Objective-C bridge.<br><br>The principles of the Objective-C syntax is that it is a small set of<br>extensions over the syntax of the base language (C in the case of<br>Objective-C).  Namely:<br><br>- message sending expressions are put inside brackets (inspired from<br>  Smalltalk block notation), and have basically the Smalltalk message<br>  sending syntax.<br><br>- class declarations and definitions (interface and implementation)<br>  and other Objective-C specific elements use keywords prefixed by the<br>  #\\@ character.<br><br><br>The later is a little at odd with lisp nature, where every form is an<br>expression, and where parenthesized syntax is prefered.  We will<br>therefore provide a more Smalltalk-like way to define classes and<br>methods (while retaining the #\\@ character as prefix for some<br>symbols, and as a reader macro to read Objective-C string literals).<br><br><br>Principles<br>----------<br><br>Two reader macros are provided:<br><br>- a reader macro bound to #\\[ is used to parse message sending<br>  expressions, just like in Objective-C, but since the underlying<br>  language is lisp, sub-expressions starting with parentheses are read<br>  just like normal sexps (they may further contain Objective-CL syntax).<br><br>- a reader macro bound to #\\@ which is used to read:<br><br>    - an Objective-C literal strings when followed by a double-quote<br>      starting a lisp string.<br><br>    - a class or method definition expression, when followed by an<br>      opening bracket #\\[.  The syntax used for these definition<br>      expression is similar to the message sending syntax, but it's<br>      processed more like a special operator or macro than a real<br>      message sending: the sub-expression are evaluated with different<br>      rules that depend on the operation.  It's called a pseudo-message.<br><br>    - a normal lisp symbol otherwise.<br><br>¶<br><br>These reader macros expand to normal lisp forms, using symbols<br>exported from a portability layer package, nicknamed OCLO, which<br>should be implemented specifically for each Objective-C bridge or FFI.<br>The implementation of this bridge is out of scope of these syntax-<br>providing reader macros.<br><br><br>Message Sending<br>---------------<br><br>The syntax is: ::<br><br>    objcl-message-expr := '[' message-send  ']' .<br><br>    message-send       := recipient message .<br>    recipient          := sexp | class-name | 'super' | 'self' .<br>    class-name         := objcl-identifier .<br><br>    message            := simple-selector | compound-selector final-arguments .<br><br>    simple-selector    := objcl-identifier .<br>    compound-selector  := objcl-identifier ':' sexp compound-selector<br>                        | objcl-identifier ':' sexp .<br>    final-arguments    := | '(' type-identifier ')' sexp  final-arguments .<br>    type-identifier    := symbol .<br><br><br>    -- FIXME type-identifier; perhaps we need:<br>    -- type-identifier   := symbol | symbol sexp .<br>    -- for example: (char *)cString (array (int 10))tenInts ?<br>    -- Check with what is available at the FFI/bridge level.<br><br><br>An ``objcl-identifier`` is a case sensitive identifier that is converted<br>to a lisp symbol according to the rules of Objective-C to Common Lisp<br>identifier translation.<br><br>A ``sexp`` is a normal lisp expression, which might be another message<br>sending bracketed expression (or another Objective-CL form).<br><br>There should be no space between the ``objcl-identifier`` and the colon.<br>After the first ``objcl-identifier`` in a compound-selector, the<br>remaining ``objcl-identifiers`` can be absent, in which case the colon<br>must be separated from the previous expression by a space.<br><br><br>When recipient is ``super``, an ``(oclo:send-super self ...)`` form is returned.<br>FIXME document the other forms returned.<br><br>Examples: ::<br><br>    [self update]<br><br>    [window orderFront:sender]<br><br>    [array performSelector:(@selector "drawRect:") withObject:rect]<br><br>    (let ((o [[NSObject alloc] init])) <br>       [NSArray arrayWithObjects:o (id)o (id)o (id)nil])<br><br><br>    '[array performSelector:(@selector "drawRect:") withObject:rect]<br>    → (OBJC:SEND ARRAY :PERFORM-SELECTOR (@SELECTOR "drawRect:") :WITH-OBJECT RECT)<br><br>Class definition<br>----------------<br><br>Classes are created by sending a ``subClass:slots:`` pseudo-message to its superclass.<br><br>The syntax is : ::<br><br>    objcl-definition    := '@[' class-definition | instance-method-definition | class-method-definition ']' .<br><br>    class-definition           := super-class-name 'subClass:' class-name  'slots:' '(' slots ')' .<br><br>    class-name         := objcl-identifier .<br>    super-class-name   := objcl-identifier .<br>    slots              := | slot slots .<br>    slot               := lisp-slot | objcl-slot .<br>    lisp-slot          := slot-specifier . -- see clhs defclass.<br><br><br>    -- objcl-slot         := ...           -- not defined yet. <br>    -- We'd want some simplified definition, and using Obj-C names.<br><br><br>Examples: ::<br><br>    @[NSObject subClass:SpaceShip<br>                  slots:((position :accessor ship-position :initform (make-position))<br>                         (speed    :accessor ship-speed    :initform 0.0))]<br><br><br>Method definition<br>-----------------<br><br>Class and instance methods are defined by sending a pseudo-message to<br>the class, either ``method:resultType:body:`` to create an instance<br>method, or ``classMethod:resultType:body:`` to create a class method.<br><br><br>The syntax is : ::<br><br>    objcl-definition    := '@[' class-definition | instance-method-definition | class-method-definition ']' .<br><br>    instance-method-definition := class-name 'method:' '(' signature ')'<br>                                         'resultType:' '(' type-identifier ')'<br>                                               'body:' body .<br><br>    class-method-definition    := class-name 'classMethod:' '(' signature ')'<br>                                              'resultType:' '(' type-identifier ')'<br>                                                    'body:' body .<br><br>    class-name         := objcl-identifier .<br>    signature          := simple-signature | compound-signature final-signature .<br>    simple-signature   := objcl-identifier .<br>    compound-signature := objcl-identifier ':' '(' type-identifier ')' objcl-identifier compound-signature<br>                        | objcl-identifier ':' '(' type-identifier ')' objcl-identifier .<br>    final-signature    := '&rest' objcl-identifier .<br>    body               := | sexp body .<br><br>    -- FIXME type-identifier; perhaps we need:<br>    -- type-identifier   := symbol | symbol sexp .<br>    -- for example: (char *)cString (array (int 10))tenInts ?<br>    -- Check with what is available at the FFI/bridge level.<br><br>There should be no space between the ``objcl-identifier`` and the colon.<br>After the first ``objcl-identifier`` in a compound-selector, the<br>remaining ``objcl-identifiers`` can be absent, in which case the colon<br>must be separated from the previous expression by a space.<br><br>Examples: ::<br><br>    @[SpaceShip classMethod:(shipAtPosition:(Position)aPosition)<br>                 resultType:(id)<br>                       body:(let ((new-ship [[self alloc] init]))<br>                               [new-ship setPosition:aPosition]<br>                               new-ship)]<br><br>    @[SpaceShip method:(moveToward:(Direction)aDirection atSpeed:(double)velocity)<br>            resultType:(id)<br>                  body:(let ((new-pos [[self position] offset:...]))<br>                         (do-something new-pos)<br>                         [self setPosition:new-pos])]<br><br>String literals<br>---------------<br><br>The syntax read is: ::<br><br>    objcl-string-literal := '@"' { character } '"' .<br><br>A CL string is read (ie. with the same escaping rules as normal CL<br>strings), and an (oclo:@ "string") form is returned.<br><br>Examples: ::<br><br>    @"Untitled"<br>    @"String with \"quotes\" and \\ backslash."<br>    @"String with<br>    new lines"<br><br><br><br><br><br>-- <br>__Pascal Bourguignon__                     http://www.informatimago.com/<br>A bad day in () is better than a good day in {}.<br><br>_______________________________________________<br>Openmcl-devel mailing list<br>Openmcl-devel@clozure.com<br>http://clozure.com/mailman/listinfo/openmcl-devel<br></div></blockquote></div><br><div>
<span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><p style="margin: 0.0px 0.0px 0.0px 0.0px"><font face="Helvetica" size="3" style="font: 12.0px Helvetica">Prof. Alexander Repenning</font></p><p style="margin: 0.0px 0.0px 0.0px 0.0px"><br class="khtml-block-placeholder"></p><p style="margin: 0.0px 0.0px 0.0px 0.0px">University of Colorado</p><p style="margin: 0.0px 0.0px 0.0px 0.0px">Computer Science Department</p><p style="margin: 0.0px 0.0px 0.0px 0.0px">Boulder, CO 80309-430</p><p style="margin: 0.0px 0.0px 0.0px 0.0px"><br class="khtml-block-placeholder"></p><p style="margin: 0.0px 0.0px 0.0px 0.0px"><font face="Helvetica" size="3" style="font: 12.0px Helvetica">vCard: <a href="http://www.cs.colorado.edu/~ralex/AlexanderRepenning.vcf">http://www.cs.colorado.edu/~ralex/AlexanderRepenning.vcf</a></font></p><br class="Apple-interchange-newline"></span></span></span></span>
</div>
<br></body></html>