help-smalltalk
[Top][All Lists]
Advanced

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

Re: [Help-smalltalk] [RFC] Smalltalk scripting syntax


From: Paul D. Fernhout
Subject: Re: [Help-smalltalk] [RFC] Smalltalk scripting syntax
Date: Fri, 09 Mar 2007 21:45:13 -0500
User-agent: Icedove 1.5.0.9 (X11/20061220)

If you are going to muck with the fileout/filein syntax, then why not
add a Python style triple quote to the language syntqx? Such a triple
quote collects everything, including newlines, up until the next triple
quote.
  http://www.python.org/doc/1.5.1p1/tut/strings.html

I'm not sure what the best semantics are for embedding triple quotes
nested inside method source -- you can always escape each quote
character or perhaps just the first.

I'd also suggest each method be individually assigned. This is useful
when you just want to add to an existing class, plus it also
makes long files easier to understand since you know what class each
method goes with.

Naturally, code processing tools may sometimes want to parse this in a
way other than immediately evaluating it. But, the lazy way of
processing a filein then becomes just evaluating it. So, add triple
quote to the Smalltalk parser, and a few methods for Class and Method(?)
and you don't need to write much more.

Then you can generalize your approach here, so that the filein format
becomes the same as evaluable Smalltalk.

Note that this eliminates all the extra brackets.

For example, to modify part of Queens.st:

============ START EXAMPLE ============

Class defineWithName: #NullChessPiece extends: Object;
    category: 'Examples-Classic'.

'Note that now we can assume NullChessPiece is defined.
Also not how we can embed comments'

NullChessPiece addMethodFromSource: """
    do: aBlock
        "Evaluate aBlock passing all the remaining solutions"
        | result |
        [ result := self next. result notNil ] whileTrue: [
            aBlock value: result
        ]
"""; category: 'enumerating'.

NullChessPiece addMethodFromSource: """
    next
        "Answer a solution, or nil if there aren't anymore"
        ^self move
            ifTrue: [ self result ]
            ifFalse: [ nil ]
"""; category: 'enumerating'.

NullChessPiece addMethodFromSource: """
    foo
        "Demonstrate embedded triple quote"
        Transcript show: \"""This is some text
which is going to have embedded newlines.
It's also got "quote" and apostrophe marks embedded.
\""".
         ^self
""""; category: 'testing'; author: 'pdf'; status: 'requires review'.

' comment about the end of code definitions;
some more would go above, like for Queen.'

"""Now, let's do something! (By the way, this string with an embedded
single quote followed by a period will just be thrown away by the filein
code, so triple quote also almost works as a comment.) """.

(Queen test: 8) printNl.

========== END EXAMPLE ========

Note that #addMethodFromSource: would return some sort of method object,
which you can then use in a cascade to do things with like annotate it
or set a category. And #defineWithName:extends: would return a Class.
If you made the category mandatory or part of a message pattern, then
you could eliminate the semicolon for at least part of the cascades.

There are probably arguments one could make about this approach
including that it might make code analysis harder to do statically when
loading since anything could be inside those triple quotes. However, in
practice, you need to do some parsing anyway, and the top level reader
could create a namespace with an alternative Class object defined and
use that to do the reading, including generating proxy objects as psuedo
classes to process the methods, and then one could analyze the results
before accepting them into the system.

Note also that this approach opens up the system for alternative
syntaxes. Such as:

NullChessPiece addMethodFromCSource: """
  OBJECT unsafeFastAdd(OBJECT self, OBJECT x, OBJECT y)
    {
    printf("unsafeFastAdd called\n");
    // the following code may crash the VM
    // if the arguments are not small integers
    // no testing is done for performance reasons
    // which is probably really not very wise in the long term.
    // But if you can't crash it, you're not doing the driving. :-)
    return int_to_st(st_to_int(x) + st_to_int(y));
    }
""""

NullChessPiece addMethodFromLispSource: """
  ; the following code may crash the VM spectacularly :-)
  (defmethod unsafeSquare (self x)
     ; the next line prints information about the object
     ; which this method was called for
     ; by calling into Smalltalk and converting the result
     ; from a Smalltalk string to a LISP string
     (debugPrint 'unsafeSquareCalledFor:
        (st_to_string (st_unary_dispatch self 'printString))
     )
     ; now let's square something without type checking!
     ; they had better be smallints or who knows what will happen?
     ; probably a LISP exception bubbling up into Smalltalk. :-)
     (int_to_st
       (* st_to_int(x) st_to_int(x))
     )
   )
""""

Anyway, my two cents. :-)

--Paul Fernhout

Paolo Bonzini wrote:
> Hi everybody,
> 
> in the next few months, Daniele Sciascia will work on the
> implementation of a scripting syntax for GNU Smalltalk.
> The aim of this is to provide a better programming experience
> than is possible with the file-out (bang-separated chunks)
> format.
> 
> This is an ambitious project, and it is best if no false
> starts are made on the syntax.  Therefore, I am attaching
> two examples (taken from RandomInt.st and Queens.st in the
> gst distribution) converted to the new syntax.
> 
> (We still have no parser, so I'm not completely sure that
> it will work exactly as I attach it, but it is enough to
> give the idea).
> 
> Speak now if you wish. :-)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]