[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: LFM + LFSP = LFE?




Clearly, what we need here is a new delimiter! ;-)  Overloading an existing
delimiter is icky.

Unfortunately, all the delimiters appear to be used in Smalltalk (the
tyranny of ascii strikes again; now I know how the APL developers felt).
You can specify weird stuff like

Object subclass: #Foo 
@{
     bar @{
         "code goes here"
     }@
}@

to artificially generate a new delimiter, but the cure is worse than the
disease.  Look at what GNU smalltalk looks like:

    Number subclass: #Integer
           instanceVariableNames: ''
           classVariableNames: ''
           poolDictionaries: 'CSymbols'
           category: 'Language-Data types'
    !
    
    Integer comment:
    'I am the abstract integer class of the GNU Smalltalk system.  My
    subclasses'' instances can represent signed integers of various
    sizes (a subclass is picked according to the size), with varying
    efficiency.' !

    !Integer methodsFor: 'iterators'!

    timesRepeat: aBlock
        "Evaluate aBlock a number of times equal to the receiver's value.
         Compiled in-line for no argument aBlocks without temporaries, and
         therefore not overridable."
        1 to: self do: [ :each | aBlock value ]
    ! !

What would we like this to look like?  There are a bunch of issues here.
I would like to see something roughly like this:

    class Integer (Number)
    {
        instanceVariableNames: ''
        classVariableNames: ''
        poolDictionaries: 'CSymbols'
        category: 'Language-Data types'.

        method timesRepeat: aBlock
        {
            "Evaluate aBlock a number of times equal to the receiver's value.
             Compiled in-line for no argument aBlocks without temporaries, and
             therefore not overridable."
            1 to: self do: [ :each | aBlock value ]
        }
    }
    
Note that in addition to the new use of {}, you have new keywords: class
and method.  You would also have to have classMethod as well.  If you don't
like keywords you can prepend a "@" to them e.g. @class, @method, but my
preference is to have a few more keywords.

Ruby seems to have done something like this, but (IMO) went overboard in
the syntax.

Mike


> Date: Sat, 14 Jun 2003 14:45:08 -0700 (PDT)
> From: Avi Bryant <avi@beta4.com>
> 
> On Sat, 14 Jun 2003, Michael Vanier wrote:
> 
> > This syntax looks decent.  One question: is it "just syntax" or can one
> > regard the block containing the method bodies as a message being sent to a
> > class?  Given my knowledge of ST syntax, I'd say it's the latter (no method
> > selector), and that will annoy the purists.  But then, I'm not a purist ;-)
> 
> Yup, it's "just syntax", and yes, that offends my sense of purity.
> Realistically, though, there are only two ways I can think of that you
> could make it a message send:
> 
> - use String literals for the method source.  Maybe you could use curly
> braces as a "smart" literal syntax that didn't need much escaping, so you
> would get
> 
> Script compile: {
>   run
>    self puts: 'hello world'
> }
> 
> for every method.  This isn't very interesting, though.
> 
> - use a block to define each method.  In the simplest case this would
> probably look something like:
> 
> Script addMethod: #run do:
>   [:self |
>   self puts: 'hello world']
> 
> or
> 
> Script addMethod: #add:to: do:
>   [:self :x :y |
>   x + y]
> 
> To properly match the return semantics, you would have to pass a
> continuation in as well:
> 
> Script addMethod: #add:to: do:
>   [:self :return :x :y |
>   return value: x + y]
> 
> I guess you could use the {} literal syntax to make this a little
> friendlier, by defining #methods: to take associations from selectors to
> blocks:
> 
> Script methods:
>  {#run ->
>    [:self :return | self puts: 'hello world'].
> 
>   #add:to: ->
>     [:self :return :x :y | return value: x + y]}
> 
> If you got really clever you could make "self" and "return" be dynamically
> scoped globals, so now we'd have something like
> 
> Script methods:
>   {#run -> [Self puts: 'hello world'].
>    #add:to: -> [:x :y | Return value: x + y]}
> 
> Comments?
> 
> Avi
>