Whither SmallScript? (was Re: Integer micro-benchmarks)
David Simmons
pulsar at qks.com
Sat Apr 28 16:26:00 EDT 2001
"Andrew Hunt" <andy at toolshed.com> wrote in message
news:slrn9ejav8.lma.andy at workbench.toolshed.com...
> On Fri, 27 Apr 2001 16:33:05 GMT, Steve Holden <sholden at holdenweb.com>
wrote:
Hi /\ndy,
About an hour or so after your last post to me, I realized you're one of the
two authors on the "Programming Ruby" book.
Which, of course, was the Ruby book I was telling you I had ;-).
...snip...
>
> I personally like the style and dynacism of Ruby. For instance, to
declare
> a class that inherits from another class you simply have:
>
> class Foo < Bar
> def myMethod
> File.new ("test.dat", "w") { |f|
> f.puts "Hello world!"
> }
> end
> end
A SmallScript version could be written as:
=========================================
class name=Foo extends=Bar {
method {
myMethod
File('test.dat','w') << 'Hello world!'.
}
}
<!-- Run it here -->
{Foo().myMethod}
======
--- OR as single line scripts with just:
{File('test.dat','w') << 'Hello world!'}
--- OR ---
{File('test.dat','w').write('Hello world!')}
--- OR ---
{File('test.dat','w').puts('Hello world!')}
=========================================
The above assumes you have a class <File> with a constructor that takes two
arguments (<aFilePath>,<aFilePermissions>) which returns instances that
implement the <IStream> interface. The "garbage collector and/or exit"
finalization will automatically close the <File> streams left open in the
above examples.
The same SmallScript compiler will also process this (XML form of Smalltalk)
identically:
=============================
<class name=Foo extends=Bar>
<?method class=Foo [ "<-- specifying class is unnecessary"
myMethod
(File open: 'test.dat' withPermissions: 'w')
nextPutAll: 'Hello world!'
]?>
</class>
[Foo new myMethod].
--- Which is Equivalent To ---
class name=Foo extends=Bar.
method class=Foo [
myMethod
(File open: 'test.dat' withPermissions: 'w')
nextPutAll: 'Hello world!'
].
[Foo new myMethod].
---
[(File open: 'test.dat' withPermissions: 'w') nextPutAll: 'Hello world!']
=============================
But perhaps more interesting is when we want to use module packaging,
namespace (scope) binding, and argument typing, as in the following script.
NOTE: Without all the numerous explanatory comments, the following code is
simple.
====================
module name=MyModule dll=Kernel32
{
<!--
Description: Within our module, override any <String> arg calls
to <File> #write(<>) or #puts(<>).
Note: The subsequent 'module=MyModule' attribute is redundant
because it is implied by nesting a method for an
external
class within our (deployment packaging) module.
-->
method class=File scope=MyModule module=MyModule
{ "" ^- Scope limits visibility of this method
::write(<>) "" <- declare an alternate name for this method
puts(<String> aString)
" ^- limits method binding to types of Strings"
/*
When we are invoked, log a message to stderr
and then invoke the general version.
*/
"Because we declared that our module act as a namespace for the
Kernel32.DLL, via dll=, we can call any of its entry points
without needing to declare them."
| fileName | := String(MAX_FILE_PATH).
fileName.size(GetModuleFileName(null,fileName,fileName.size)).
"" Log the message here
stderr << '`nWe just used a custom File::write(<>) version'.
' from module: ' << fileName.
"" Invoke the standard write routine here
return self::File.write(aString)
(*
We could have qualified the #write message via these
other forms:
self #File.write(...)
self #::File.write(...)
*)
}
<!-- Now execute custom version -->
{File('test.dat','w'.puts('Hello world!`n')}
<!-- Now execute standard version because of type discrimination -->
{File('test.dat','w'.puts(42)}
}
<!-- Now execute standard version because this eval/immediate method
is outside the module scope -->
{File('test.dat','w'.puts('`nHello world!')}
====================
I intentionally used a wide variety of the different comment styles allowed
(there are additional forms including Unicode variants). The comment forms
also enable an extensible form of JavaDoc.
Normally, I would adopt one comment style and use it consistently.
I should also point out that, in general, the SmallScript parse tree
facilities enable an IDE or similar tool to rewrite/transform/present source
code into either of the various SmallScript and Smalltalk like styles that
were shown in these examples.
-- Dave S.
>
> Here, class Foo inherits from class Bar. Except that class Bar is just an
> expression that returns a Class object. In this case it's a constant, but
> you could just as easily have:
>
> class Foo < someMagicRoutine(someArgument, somethingElse)
>
> File is a real object, we'll call open on it. The opened file object is
> passed to the block as local variable f, where we can call puts (named as
> in libc) to put a string to the file. At the conclusion of the block,
> the file is closed automatically.
>
> Doesn't look much like Perl to me. Oh, and that's just one way to
> use files -- you don't have to use them in a block, but I find it
> handy to make sure I've really closed a file :-)
>
>
> /\ndy
>
> --
> Andrew Hunt, The Pragmatic Programmers, LLC.
> Innovative Object-Oriented Software Development
> web: http://www.pragmaticprogrammer.com email:
andy at pragmaticprogrammer.com
> --
> Books by Andrew Hunt and David Thomas:
> "The Pragmatic Programmer" (Addison-Wesley 2000)
> "Programming Ruby" (Addison-Wesley 2001)
> --
More information about the Python-list
mailing list