[RFC] Smalltalk scripting syntax

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
52 messages Options
123
Reply | Threaded
Open this post in threaded view
|

[RFC] Smalltalk scripting syntax

Paolo Bonzini
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. :-)

Paolo

Class name: Integer extends: RandomInteger [
    <comment: 'My instances are random integers'>
    <category: 'Examples-Useful'>

    "Define a class variable"
    Source := Random new.

    "Define class methods.  An alternative syntax for this is shown
     in the Queens example (both are acceptable)."
    Class name: RandomInteger class [
        new [
            <category: 'instance creation'>
            ^self error: 'Must use between:and:'
        ]

        between: low and: high [
            <category: 'instance creation'>
            | i range |

            (Source = nil) ifTrue: [ Source := Random new ].
            range := high - low + 1.
            i := (Source next * range) truncated.
            ^i + low
        ]
    ]
]


Class name: NullChessPiece extends: Object [
    <category: 'Examples-Classic'>

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

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

    result [
        "Answer all the queens' rows, up to and including the receiver"
        <category: 'enumerating'>
        ^OrderedCollection new
    ]

    move [
        "Move the queen so that it is not menaced, backtracking if necessary.
         Answer whether a position can be found.
         If the null queen is asked to advance, the search tree has been walked
         entirely - so return false."
        <category: 'solving'>
        ^false
    ]

    menaces: test [
        "Answer whether a queen is menaced in the given position by the queens
         up to and including the receiver. The null queen does not menace
         anything."
        <category: 'solving'>
        ^false
    ]
]

Class: ChessPiece extends: NullChessPiece [
    | row column neighbor rows |

    <category: 'Examples-Classic'>

    ChessPiece class >> test: side [
        <category: 'testing'>
        | line n |
        (line := String new: side * 2 + 1)
            atAll: (1 to: side * 2 + 1 by: 2) put: $|;
            atAll: (2 to: side * 2 + 1 by: 2) put: $_.

        n := 0.
        (self board: side) do: [ :result |
            n := n + 1.
            Transcript
                space;
                next: side * 2 - 1 put: $_;
                nl.

            result do: [:x |
           line at: x + x put: $*.
           Transcript nextPutAll: line; nl.
           line at: x + x put: $_.
            ].
            Transcript nl.
        ].
        Transcript nl.
        ^n
    ]

    ChessPiece class >> board: n [
        <category: 'instance creation'>

        "Answer a ChessPiece which will return results for a chessboard of
         side n"
        ^(1 to: n) inject: NullChessPiece new into: [ :neighbor :column |
            self new
                setColumn: column
                rows: n
                neighbor: neighbor
        ]
    ]

    setColumn: aNumber rows: n neighbor: aChessPiece [
        "Initialize the receiver to work on column aNumber of a chessboard of
         side n, having aChessPiece as a neighbor"
        <category: 'private'>

        column := aNumber.
        rows := n.
        neighbor := aChessPiece.
        row := 0.
   
        "Put all the queens but the last in some place where they are safe. The
         last will be requested by sending #next"
        self neighbor move.
        ^self
    ]

    advance [
        "Move the receiver one row further if possible, else backtrack and move
         to the first row. Answer whether there was a safe position for the
         neighbor (in the first case, the neighbor was already in a safe
         position, so answer true!)"
        <category: 'solving'>

        ^row = rows
            ifTrue: [ row := 1. self neighbor move ]
            ifFalse: [ row := row + 1. true ].
    ]

    row [
        <category: 'accessing'>
  ^row
    ]

    column [
        <category: 'accessing'>
        ^column
    ]

    neighbor [
        <category: 'accessing'>
        ^neighbor
    ]

    menaces: test [
        <category: 'inherited'>
        "Answer whether the receiver or any of the pieces above it menace the
         `test' piece if it stays where its #row and #column methods say.
         This method will test if the receiver itself menaces the tested
         piece and if not will delegate the choice to the neighbor."
        self subclassResponsibility
    ]

    move [
        <category: 'inherited'>
        "Here and in #advance is where the search really takes place.
         We advance the queen to the next cell; if the edge has been reached,
         #advance takes care of backtracking by sending #move to the neighbor
         (which in turn could backtrack).  If the queen is safe there, return
         true; else we advance the queen once more and check again.
         Sooner or later every queen will be aligned on the right edge and each
         one will be ask its neighbor to advance.  So the first queen will send
         #move to the NullChessPiece, the NullChessPiece will answer false, and
         all the invocations of #move will in turn answer false, terminating the
         search."
        [   self advance ifFalse: [ ^false ].
            self neighbor menaces: self
        ] whileTrue: [ ].
        ^true
    ]


    result [
        <category: 'inherited'>
        ^self neighbor result
            addLast: row;
            yourself
    ]
]


Class name: Queen extends: ChessPiece [
    <category: 'Examples-Classic'>

    menaces: test [
        "Answer whether the receiver or any of the pieces above it menace the
         `test' piece if it stays where its #row and #column methods say."
        <category: 'inherited'>

        | columnDifference rowDifference |
        columnDifference := (test column - self column) abs.
        rowDifference := (test row - self row) abs.

        rowDifference = 0 ifTrue: [ ^true ].
        rowDifference = columnDifference ifTrue: [ ^true ].

        ^self neighbor menaces: test
    ]
]

(Queen test: 8) printNl.

_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Stefan Schmiedl
Paolo Bonzini (09.03. 09:00):

> Speak now if you wish. :-)

I like it. The syntax looks very typeable on a German keyboard
and should be not hard to follow for basic syntax coloring.

If

> Class name: NullChessPiece extends: Object [

shouldn't the line

> Class name: Integer extends: RandomInteger [

read instead

> Class name: RandomInteger extends: Integer


Good luck for this project!

s.

--
Stefan Schmiedl
+-------------------------------+----------------------------------------+
|Approximity GmbH               | EDV-Beratung Schmiedl                  |
|http://www.approximity.com     | Am Bräuweiher 4, 93499 Zandt, Germany  |
|mailto:[hidden email]  | Tel. (09944) 3068-98, Fax -97          |
+-------------------------------+----------------------------------------+


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Paolo Bonzini

>> Speak now if you wish. :-)
>
> I like it. The syntax looks very typeable on a German keyboard
> and should be not hard to follow for basic syntax coloring.
>
> If
>
>> Class name: NullChessPiece extends: Object [
>
> shouldn't the line
>
>> Class name: Integer extends: RandomInteger [
>
> read instead
>
>> Class name: RandomInteger extends: Integer

Yes of course.

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Stefan Schmiedl
Paolo Bonzini (09.03. 09:47):

>
> >> Speak now if you wish. :-)
> >
> > I like it. The syntax looks very typeable on a German keyboard
> > and should be not hard to follow for basic syntax coloring.
> >
> > If
> >
> >> Class name: NullChessPiece extends: Object [
> >
> > shouldn't the line
> >
> >> Class name: Integer extends: RandomInteger [
> >
> > read instead
> >
> >> Class name: RandomInteger extends: Integer
>
> Yes of course.

A *very* readable syntax, obviously. You can find errors even without a
spec :-)

s.


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Chun, Sungjin
In reply to this post by Paolo Bonzini
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

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.
>

Wow, great!

>
> Speak now if you wish. :-)
>
> Paolo
>

OK, then....

What about +/- for class/instance method like Objective-C? I think your
example is rather complex for defining class/instance method. For other
parts I actually does not have good/bad points.

Bye.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF8TOWQqspS1+XJHgRAj+qAJwNM3jfCFSiqGsqHnvC58xbVPZbFgCdHOTq
pxbGCEd+N12PbWGfCkeGgXQ=
=y8+h
-----END PGP SIGNATURE-----


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Stefan Schmiedl
Sungjin Chun (09.03. 19:14):

> What about +/- for class/instance method like Objective-C? I think your
> example is rather complex for defining class/instance method. For other
> parts I actually does not have good/bad points.

It looks very Smalltalk-ish to me, favoring message sends above complex
syntax.

s.


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Paolo Bonzini
In reply to this post by Chun, Sungjin

> What about +/- for class/instance method like Objective-C? I think your
> example is rather complex for defining class/instance method. For other
> parts I actually does not have good/bad points.

If I head written #new as an instance method, for example, I think
Stefan (or somebody else for him) could have spotted the problem
with this syntax.  I find instead very confusing to remember which
of +/- is a class and which is an instance method.

Also, UML has hijacked +/- for public/private respectively, which
can only add to the confusion.

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Chun, Sungjin
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

In fact, I just want more less typing and easy-to-remember syntax for
this. +/- is just from my experience in Obj-C. Other syntax which is
rather simple will be OK.

Sungjin.

Paolo Bonzini wrote:

>> What about +/- for class/instance method like Objective-C? I think your
>> example is rather complex for defining class/instance method. For other
>> parts I actually does not have good/bad points.
>
> If I head written #new as an instance method, for example, I think
> Stefan (or somebody else for him) could have spotted the problem
> with this syntax.  I find instead very confusing to remember which
> of +/- is a class and which is an instance method.
>
> Also, UML has hijacked +/- for public/private respectively, which
> can only add to the confusion.
>
> Paolo

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF8gDQQqspS1+XJHgRAku0AKDgvnF5Qb/CByOy0M/wflv5qyEJmgCgqtIY
Pks9et8zZGqg+taWZJ0P0OY=
=ufPY
-----END PGP SIGNATURE-----


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Jānis Rūcis
In reply to this post by Paolo Bonzini
I'm resending this mail because I think I messed something up and it
didn't make it to the list.  Sorry for any inconvenience.

Thanks,
Jānis

-------------------------------------------------------------------

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.

Hi Paolo.  First of all, I have only been reading this list for a couple
of months, so I might not be aware of all the reasons behind such
changes.  I did find and read a related discussion[1] in the archives,
though.  If there's anything I'm missing, please let me know.

I'm also a Smalltalker for a bit longer than I've been reading this
list, but one thing that I can immediately name as the reason I'm not
looking back is the single-paradigm approach which actually works and is
well reflected in Smalltalk's own syntax.  Which in turn is the main
reason why I prefer the bang-separated format over the proposed.

The biggest issues I have with the syntax are:

  * block-like delimiters

First, they're block-like, but they're not really blocks, which is
nothing but confusing.  Second, the introduction of these seems to be a
step in a direction other than where most "modern" languages, such as
Ruby, Python or Lua, are headed.  They use keywords, a keyword, or even
white space to separate chunks.  Even without following "the lead",
using a bang seems like a non-intrusive (brackets degrade readability)
and natural (with respect to Smalltalk's use of semi-colons and periods)
solution.

  * <keyword: some arguments> syntax

This is something I'm not fond of in the bang-separated format either.
Special syntax for call-ins is acceptable (as a preprocessor kind of
thing), but is not for integral stuff such as class comments and
class/method categories.

  * class and method definitions

By that I mean things such as "Class name: NullChessPiece extends:
Object [" and "ChessPiece class >> test: side [".  They look like
message sends, with the difference that one of them references an
undefined variable "NullChessPiece" and both contain syntax errors.  If
they're meant to look like message sends, then please make them look
like valid message sends.  Or, you could make them look entirely
different, but that would just introduce another special case in the syntax.

Then there are also a few minor other things that most people would not
find to be a problem at all:

  * "Object subclass: #SomeClass" is shorter and more to the point than
"Class name: SomeClass extends: Object".

  * Readability issues in message definitions where

      <category> is followed by a
      "comment", some
      | temporary variables |, and an
      ^answer.  That's now four kinds of delimiters/operators each on
its own line.

  * Class method definitions alongside instance method definitions is messy.

  * Category per method seems redundant.  There are usually several
methods per category.

Of course, I should say that none of this is a big deal if the changes
are made entirely optional.  But I really like to think that they got it
right in the seventies and that the minimalistic bang-separated format
pretty much follows that approach.

Best,
Jānis Rūcis

[1] http://lists.gnu.org/archive/html/help-smalltalk/2006-09/msg00095.html




_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Paul D. Fernhout
In reply to this post by Paolo Bonzini
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. :-)


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Paul D. Fernhout
Sorry, two of those Smalltalk comments between code chunks incorrectly
have single quotes instead of double quotes; sadly, not enough
Smalltalking these days. :-(

As it is written, evaluation would produce a runtime error just before
the first addMethodFromSource: of "String does not understand
#NullChessPiece". And if that comment was corrected, possibly the rest
would work assuming the compiler merges the string starting with '
comment about...' with the subsequent triple quoted string starting with
"""Now, let's ...""" . :-)

Now this brings up another issues, which is that getting an error like
"String does not understand #NullChessPiece" when doing a filein would
be confusing for anybody, especially a novice. But as long as the error
message could be tied back into the location in the file, presumably the
error would be noticed eventually.

--Paul Fernhout



_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Mike Anderson-3
In reply to this post by Jānis Rūcis
parasti wrote:

> 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.
>
> Hi Paolo.  First of all, I have only been reading this list for a couple
> of months, so I might not be aware of all the reasons behind such
> changes.  I did find and read a related discussion[1] in the archives,
> though.  If there's anything I'm missing, please let me know.
>
> I'm also a Smalltalker for a bit longer than I've been reading this
> list, but one thing that I can immediately name as the reason I'm not
> looking back is the single-paradigm approach which actually works and is
> well reflected in Smalltalk's own syntax.  Which in turn is the main
> reason why I prefer the bang-separated format over the proposed.
>
> The biggest issues I have with the syntax are:
>
>   * block-like delimiters
>
> First, they're block-like, but they're not really blocks, which is
> nothing but confusing.  Second, the introduction of these seems to be a
> step in a direction other than where most "modern" languages, such as
> Ruby, Python or Lua, are headed.  They use keywords, a keyword, or even
> white space to separate chunks.  Even without following "the lead",
> using a bang seems like a non-intrusive (brackets degrade readability)
> and natural (with respect to Smalltalk's use of semi-colons and periods)
> solution.

Hi Jānis,

My personal feeling is that you can regard [] as indicating a block of
code (not a BlockClosure) with deferred execution, as opposed to (),
which indicates a block of code with immediate execution. Although the
real situation is more complicated than that, I don't think that it is
particularly misleading. After all, blocks themselves can be full blocks
(closures) or not, and it is up to the programmer to recognise the
difference if it matters.

The bang-delimited syntax is difficult to parse properly, even with full
parser. This is because #methodsFor: switches the compiler from one mode
to another. If you were to wrap it in another method, the parser would
be unaware that that method is also 'special'. With the [] syntax for
methods, you do not have this modality, so the situation does not arise.

>   * <keyword: some arguments> syntax
>
> This is something I'm not fond of in the bang-separated format either.
> Special syntax for call-ins is acceptable (as a preprocessor kind of
> thing), but is not for integral stuff such as class comments and
> class/method categories.
>
>   * class and method definitions
>
> By that I mean things such as "Class name: NullChessPiece extends:
> Object [" and "ChessPiece class >> test: side [".  They look like
> message sends, with the difference that one of them references an
> undefined variable "NullChessPiece" and both contain syntax errors.  If
> they're meant to look like message sends, then please make them look
> like valid message sends.  Or, you could make them look entirely
> different, but that would just introduce another special case in the syntax.

Although I don't object to the syntax quite as much as you do, I do
think that some of the examples seem to violate the normal selector
precedence, and that is a Bad Thing. In particular this:

ChessPiece class >> test: side [ ... ]

and this:

Class name: RandomInteger class [ ... ]

> Then there are also a few minor other things that most people would not
> find to be a problem at all:
>
>   * "Object subclass: #SomeClass" is shorter and more to the point than
> "Class name: SomeClass extends: Object".

I agree. My opinion is that the first advertises the fact that
Everything Is An Object. Still, I can live with it.

>   * Readability issues in message definitions where
>
>       <category> is followed by a
>       "comment", some
>       | temporary variables |, and an
>       ^answer.  That's now four kinds of delimiters/operators each on
> its own line.

I would hope that the syntax is still free-form, and all four of those
are optional, are they not?

>   * Class method definitions alongside instance method definitions is messy.
>
>   * Category per method seems redundant.  There are usually several
> methods per category.

In a subclass, I think that tends to be untrue. One of the annoyances I
find in writing in the chunk format is having to have a separate
#methodsFor: for each new method. In fact, I tend to just shove
everything into an 'everything' category to save the effort.

> Of course, I should say that none of this is a big deal if the changes
> are made entirely optional.  But I really like to think that they got it
> right in the seventies and that the minimalistic bang-separated format
> pretty much follows that approach.
>
> Best,
> Jānis Rūcis
>
> [1] http://lists.gnu.org/archive/html/help-smalltalk/2006-09/msg00095.html



_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Mike Anderson-3
In reply to this post by Chun, Sungjin
Sungjin Chun wrote:

> Paolo Bonzini wrote:
>> Speak now if you wish. :-)
>
>> Paolo
>
>
> OK, then....
>
> What about +/- for class/instance method like Objective-C? I think your
> example is rather complex for defining class/instance method. For other
> parts I actually does not have good/bad points.
>
> Bye.

This is unrelated to the scripting syntax, but I have experimented with
adding methods #-< , #@ and #@@ on Class for #subclass:,
#addInstVarName: and #addClassVarName: respectively. This allows a
ruby-like syntax:

Object -< #TreeModel
        @ 'document'
        @@ 'NodeTypes'!

In the end, I decided that defining #subclass:, #subclass:instVarNames:
and #subclass:instVarNames:classVarNames: was a better compromise
between my need for less typing and easy-understandability for
'conventional' Smalltalkers. Still, it has its attractions.

Mike


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Mike Anderson-7
In reply to this post by Paolo Bonzini
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. :-)
>
> Paolo

It seems to me that we have never really addressed the question of how
the language is used to write actual scripts. 'Scripting' is not a
precisely defined activity, of course, but it seems to me that scripting
 often does not require defining new classes.

For example, it's perfectly possible to define classes in Perl, but for
most scripts I never do. The built-in arrays, hashes and function refs
are quite adequate for representing complex data structures. Smalltalk
has a very good set of standard classes, including Arrays
[OrderedCollections] and Dictionaries [LookupTables], and I think the
same applies.

So the question is, how do you write structured code? I find three major
issues:

a) You have to write methods in order to be able to use ^, and to have
functions. This means that you must have a class, and I find myself
declaring a bogus 'Script' class in order to accomplish this. It also
seems to involve mutating local variables into instance variables,
solely because of scope.

You can, to some extent use blocks as functions, by assigning them to
variables, but you find the the code starts to look like:

afunc value: (bfunc value: 1 value: 'two') value: true.

- complete loss of readability.

b) Having to declare variables is fine (good, in fact) in methods and
blocks. In eval chunks, I find that it becomes onerous. There are good
reasons to name your variables properly and use them for only one thing,
but if it means a trip up to the top of the file, I find that I prefer
to just reuse an existing variable.

c) Filing in packages is slow, and building an image for every script is
not a solution.

I don't have answers to these problems, but I have been thinking that
having an implicit 'Script' class for each file might satisfy (a) and (b).

Perhaps having an explicit 'Script' class is not so bad either,
particularly with the proposed style of method definition (saving the
need to write many methodsFor: statements).

Regards,

Mike


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Paolo Bonzini
In reply to this post by Mike Anderson-3

> Although I don't object to the syntax quite as much as you do, I do
> think that some of the examples seem to violate the normal selector
> precedence, and that is a Bad Thing. In particular this:
>
> ChessPiece class >> test: side [ ... ]

Note that this is no valid syntax in Smalltalk.  I see this "as if"
the "test:" keyword where an object is expected introduces a
"message pattern" which as the same precedence as an object (i.e.
very high).

> and this:
>
> Class name: RandomInteger class [ ... ]

Likewise, here the '[' where a keyword is expected introduce
a "scoped definition" which has instead a very low precedence.

It's like in standard math syntax, where "-/+" has high precedence if
it is unary, and low precedence if it is binary.

>> Then there are also a few minor other things that most people would not
>> find to be a problem at all:
>>
>>   * "Object subclass: #SomeClass" is shorter and more to the point than
>> "Class name: SomeClass extends: Object".
>
> I agree. My opinion is that the first advertises the fact that
> Everything Is An Object. Still, I can live with it.

I would prefer "Object subclass: SomeClass" (okay, I know why you would
like the hash).  If it is preferred, Daniele will implement it instead
of "Class name: SomeClass extends: Object".

The nice thing of "Class name: SomeClass extends: Object" is that it
pairs nicely with the syntax to define class extensions, which is

    Class name: SomeClass [
        ...
    ]

Please comment on this.

>>       <category> is followed by a
>>       "comment", some
>>       | temporary variables |, and an
>>       ^answer.
>
> I would hope that the syntax is still free-form, and all four of those
> are optional, are they not?

Of course.

Paolo


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Topher Cyll
In reply to this post by Mike Anderson-7
> It seems to me that we have never really addressed the question of how
> the language is used to write actual scripts. 'Scripting' is not a
> precisely defined activity, of course, but it seems to me that scripting
>  often does not require defining new classes.
>
> For example, it's perfectly possible to define classes in Perl, but for
> most scripts I never do.

I would just caution, this may be a symptom of Perl's broken class
system.  I tend not to define classes when I script in Perl either,
but when I'm scripting with Ruby (even simple things) it's not
uncommon for me to define my own classes.

Anyways, good questions you raised!
Toph


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Mike Anderson-3
In reply to this post by Paolo Bonzini
Paolo Bonzini wrote:

>> Although I don't object to the syntax quite as much as you do, I do
>> think that some of the examples seem to violate the normal selector
>> precedence, and that is a Bad Thing. In particular this:
>>
>> ChessPiece class >> test: side [ ... ]
>
> Note that this is no valid syntax in Smalltalk.  I see this "as if"
> the "test:" keyword where an object is expected introduces a
> "message pattern" which as the same precedence as an object (i.e.
> very high).
>
>> and this:
>>
>> Class name: RandomInteger class [ ... ]
>
> Likewise, here the '[' where a keyword is expected introduce
> a "scoped definition" which has instead a very low precedence.

In the bit before that,

Class name: RandomInteger class

If I interpret the syntax correctly, #class is expected to be sent last,
 which is completely contrary to the normal rules of precedence. In this
situation, I think it would be far better to abandon the pretense that
these are message sends.

Actually, this is within the definition of RandomInteger, so surely
these tokens are superfluous: 'name:', 'RandomInteger', and one of
'Class' / 'class'. Could you not save some typing and have:

class [ "class methods" ]

and

class test: side [ ... ]

?

I've found something else that bothers me:

| instance variables |

vs.

ClassVar := Random new.

I feel that these should be more similar. :)

> It's like in standard math syntax, where "-/+" has high precedence if
> it is unary, and low precedence if it is binary.
>
>>> Then there are also a few minor other things that most people would not
>>> find to be a problem at all:
>>>
>>>   * "Object subclass: #SomeClass" is shorter and more to the point than
>>> "Class name: SomeClass extends: Object".
>> I agree. My opinion is that the first advertises the fact that
>> Everything Is An Object. Still, I can live with it.
>
> I would prefer "Object subclass: SomeClass" (okay, I know why you would
> like the hash).  If it is preferred, Daniele will implement it instead
> of "Class name: SomeClass extends: Object".
>
> The nice thing of "Class name: SomeClass extends: Object" is that it
> pairs nicely with the syntax to define class extensions, which is
>
>     Class name: SomeClass [
>         ...
>     ]
>
> Please comment on this.

Couldn't you simply write:

SomeClass [
        ...
]

or have I misunderstood?

>>>       <category> is followed by a
>>>       "comment", some
>>>       | temporary variables |, and an
>>>       ^answer.
>> I would hope that the syntax is still free-form, and all four of those
>> are optional, are they not?
>
> Of course.
>
> Paolo

Thank you for unblocking my other post :)

Mike


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Mike Anderson-3
In reply to this post by Topher Cyll
Topher Cyll wrote:

>> It seems to me that we have never really addressed the question of how
>> the language is used to write actual scripts. 'Scripting' is not a
>> precisely defined activity, of course, but it seems to me that scripting
>>  often does not require defining new classes.
>>
>> For example, it's perfectly possible to define classes in Perl, but for
>> most scripts I never do.
>
> I would just caution, this may be a symptom of Perl's broken class
> system.  I tend not to define classes when I script in Perl either,
> but when I'm scripting with Ruby (even simple things) it's not
> uncommon for me to define my own classes.

Perl's class system is no more broken than C's :)

What makes you choose Perl for some scripts and Ruby for others, if you
don't mind me asking?

> Anyways, good questions you raised!
> Toph

Thank you!

Mike



_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Topher Cyll
> Perl's class system is no more broken than C's :)

Heh.

> What makes you choose Perl for some scripts and Ruby for others, if you
> don't mind me asking?

Legacy libraries.  I always pick Ruby when that's not an issue. =)

There are a lot of reasons for that choice, but having a comprehensive
closure-oriented Collection interface is a great boon while scripting
-- a benefit GST would also obviously enjoy.

Toph


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: [RFC] Smalltalk scripting syntax

Jānis Rūcis
In reply to this post by Mike Anderson-3
Hi Mike,

> My personal feeling is that you can regard [] as indicating a block of
> code (not a BlockClosure) with deferred execution, as opposed to (),
> which indicates a block of code with immediate execution. Although the
> real situation is more complicated than that, I don't think that it is
> particularly misleading. After all, blocks themselves can be full blocks
> (closures) or not, and it is up to the programmer to recognise the
> difference if it matters.
>
> The bang-delimited syntax is difficult to parse properly, even with full
> parser. This is because #methodsFor: switches the compiler from one mode
> to another. If you were to wrap it in another method, the parser would
> be unaware that that method is also 'special'. With the [] syntax for
> methods, you do not have this modality, so the situation does not arise.

Thanks for the explanation.  I had suspected that it might have
something to do the internals of the compiler, but I'm afraid I don't
know much about that.  I do, however, recognize it as a valid concern,
unlike, say, the "let's make Smalltalk accessible" approach which is
really the "let's make Smalltalk some other language" approach.  :)

To the point, what I do not really understand is why special syntax is
necessary.  I mean, why:

    Class name: SomeClass extends: Object [
        <category: 'some category'>
        printOn: aStream [
            <category: 'printing'>
            "..."
        ].
    ].

instead of:

    Object subclass: #SomeClass category: 'some category'.
    SomeClass addMethod: 'printOn: aStream' for: 'printing' as: [
        " ... "
    ].

It doesn't necessarily have to be a full-blown statement (by which I
mean that anything can be substituted for the literals), just so that it
looks like proper Smalltalk, putting emphasis on "if classes are created
by sending messages, then methods must be as well!"  Or is the special
syntax exactly the solution to the problem?  I'm quite sure that the <>
syntax is not necessary for that.

>>   * Readability issues in message definitions where
>>
>>       <category> is followed by a
>>       "comment", some
>>       | temporary variables |, and an
>>       ^answer.  That's now four kinds of delimiters/operators each on
>> its own line.
>
> I would hope that the syntax is still free-form, and all four of those
> are optional, are they not?

Of course, you're absolutely right.  :)  It's just something I use as a
general guideline when it comes to programming:  "if it looks ugly, it
probably is," and it does look ugly.  But, as I said, not everybody
would find that to be a problem.

Jānis


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
123