Discussion:
The history of VW pragmas?
(too old to reply)
Andrei N.Sobchuck
2004-10-27 10:12:36 UTC
Permalink
When pragmas where introduced?
What was the purpose?
Do pragmas exist in other Smalltalk dialects?
--
Andrei N.Sobchuck
JabberID: ***@jabber.ru. ICQ UIN: 46466235.
Vassili Bykov
2004-10-27 15:35:00 UTC
Permalink
Post by Andrei N.Sobchuck
When pragmas where introduced?
VisualWorks 3.0
Post by Andrei N.Sobchuck
What was the purpose?
Tag methods with properties one could search for and track their
addition and removal. The first use in VW 3.0 was menu extension methods.
Post by Andrei N.Sobchuck
Do pragmas exist in other Smalltalk dialects?
IBM Smalltalk/Visual Age has something they call pragmas, which appears
as special syntax inside method comments. The purpose seems to be
similar, but nothing else is.

I implemented VisualWorks-like pragmas in Squeak when working with Dan
on the Squeak port of Hobbes he shown at ESUG this year. (Available from
me, free for the asking).
--
Vassili Bykov
Tools Technical Lead, VisualWorks Engineering
v b y k o v A T c i n c o m D O T c o m
http://www.cincomsmalltalk.com/userblogs/vbykov
Avi Bryant
2004-10-28 00:24:59 UTC
Permalink
Post by Vassili Bykov
I implemented VisualWorks-like pragmas in Squeak when working with Dan
on the Squeak port of Hobbes he shown at ESUG this year. (Available from
me, free for the asking).
Why not make this available on SqueakMap? Or if you like, send the
.cs to me and I'll be happy to post it for you.

Avi
Andrei N.Sobchuck
2004-10-28 09:03:14 UTC
Permalink
Post by Andrei N.Sobchuck
When pragmas where introduced?
VB> VisualWorks 3.0

Is it 1998?
Post by Andrei N.Sobchuck
What was the purpose?
VB> Tag methods with properties one could search for and track their
VB> addition and removal. The first use in VW 3.0 was menu extension methods.

What about DLLCC? I think it uses the pragmas.
There was no such package before VW 3.0 or
it didn't use the pragmas?
--
Andrei N.Sobchuck
JabberID: ***@jabber.ru. ICQ UIN: 46466235.
Vassili Bykov
2004-10-28 16:20:30 UTC
Permalink
Post by Andrei N.Sobchuck
Post by Andrei N.Sobchuck
When pragmas where introduced?
VB> VisualWorks 3.0
Is it 1998?
Yes, it was released early that year.
Post by Andrei N.Sobchuck
Post by Andrei N.Sobchuck
What was the purpose?
VB> Tag methods with properties one could search for and track their
VB> addition and removal. The first use in VW 3.0 was menu extension methods.
What about DLLCC? I think it uses the pragmas.
There was no such package before VW 3.0 or
it didn't use the pragmas?
DLLCC was there long before, but it didn't, and still doesn't, use
pragmas. It uses declarations in angle brackets which resemble pragmas
until you look closer.

One difference is that pragmas use a subset of Smalltalk syntax--what
goes inside the brackets is a message send sans the receiver, with any
literal syntax allowed as arguments. In DLLCC, what goes after "<C:" is
a subset of C.

A more important difference is that pragmas are only method labels.
They don't change how a method is executed--Smalltalk code in those
methods runs as usual. In DLLCC and primitive methods (another
pragma-like syntax) the real work is done behind the scenes, and
Smalltalk code is there only for error handling.
--
Vassili Bykov
Tools Technical Lead, VisualWorks Engineering
v b y k o v A T c i n c o m D O T c o m
http://www.cincomsmalltalk.com/userblogs/vbykov
Eliot Miranda
2004-10-28 21:11:40 UTC
Permalink
Post by Vassili Bykov
Post by Andrei N.Sobchuck
Post by Andrei N.Sobchuck
When pragmas where introduced?
VB> VisualWorks 3.0
Is it 1998?
Yes, it was released early that year.
Post by Andrei N.Sobchuck
Post by Andrei N.Sobchuck
What was the purpose?
VB> Tag methods with properties one could search for and track their
VB> addition and removal. The first use in VW 3.0 was menu extension methods.
What about DLLCC? I think it uses the pragmas.
There was no such package before VW 3.0 or
it didn't use the pragmas?
DLLCC was there long before, but it didn't, and still doesn't, use
pragmas. It uses declarations in angle brackets which resemble pragmas
until you look closer.
One difference is that pragmas use a subset of Smalltalk syntax--what
goes inside the brackets is a message send sans the receiver, with any
literal syntax allowed as arguments. In DLLCC, what goes after "<C:" is
a subset of C.
A more important difference is that pragmas are only method labels. They
don't change how a method is executed--Smalltalk code in those methods
runs as usual. In DLLCC and primitive methods (another pragma-like
syntax) the real work is done behind the scenes, and Smalltalk code is
there only for error handling.
I don't buy this. I think of C: being a pragma and the implementation
not having caught up. #exception is a pragma (and implemented as such)
and affects the semantics. The fact that the implementation hasn't
caught up is simply historical. CPOK was introduced before we hit on a
regular implementation scheme for pragmas, at a time when for example
the primitive: pragma was implemented by bits in a method header or
specific bytecodes. If we had to do it over I think we'd be much more
regular, and all primitive: C: et al methods would answer pragma
messages, and we'd write <primitive: 123 errorCode: aTemp> as
<primitive: 123 errorCode: #aTemp>
or
<primitive: 123 errorCode: 'aTemp'>.

At least that's my take on it.
--
_______________,,,^..^,,,____________________________
Eliot Miranda Smalltalk - Scene not herd
Vassili Bykov
2004-10-29 00:47:51 UTC
Permalink
Post by Eliot Miranda
I don't buy this. I think of C: being a pragma and the implementation
not having caught up.
Call me a language lawyer, but in that case I am waiting to see BNF of
our syntax that describes things like

<C: DWORD CommDlgExtendedError(void) >

:)
Post by Eliot Miranda
#exception is a pragma (and implemented as such)
and affects the semantics. The fact that the implementation hasn't
caught up is simply historical. CPOK was introduced before we hit on a
regular implementation scheme for pragmas, at a time when for example
the primitive: pragma was implemented by bits in a method header or
specific bytecodes. If we had to do it over I think we'd be much more
regular, and all primitive: C: et al methods would answer pragma
messages, and we'd write <primitive: 123 errorCode: aTemp> as
<primitive: 123 errorCode: #aTemp>
or
<primitive: 123 errorCode: 'aTemp'>.
At least that's my take on it.
We _would_ be regular, but we are not. primitive: is still implemented
by specific bytecodes, produces a regular CompiledMethod, and is not
visible when asking for a method's #attributes. Ditto for C:.

The disagreement is about terminology (or separating intention from
implementation :-). I see how much more attractive it would be to
consider C: and primitive: as pragmas like others, and say pragmas are
anything within angle brackets. Indeed I would prefer to have them that
way. But I can't seriously consider them as such until I can do

Pragma allNamed: #primitive:errorCode: from: Foo to: Object

and use the usual interface of Pragma to reflect on the results.
#primitive: wouldn't be that hard to fit into this common Pragma scheme,
but #primitive:errorCode: might be trickier, and C: even more so with
its silly pseudo-C syntax.
--
Vassili Bykov
Tools Technical Lead, VisualWorks Engineering
v b y k o v A T c i n c o m D O T c o m
http://www.cincomsmalltalk.com/userblogs/vbykov
Eliot Miranda
2004-10-29 17:31:34 UTC
Permalink
Post by Vassili Bykov
Post by Eliot Miranda
I don't buy this. I think of C: being a pragma and the implementation
not having caught up.
Call me a language lawyer, but in that case I am waiting to see BNF of
our syntax that describes things like
<C: DWORD CommDlgExtendedError(void) >
Right. But you'd have no problem with

<C: 'WORD CommDlgExtendedError(void)'>

would you? And being able to get the type string from the pragma
instead of having to parse the method source would be useful also.
Post by Vassili Bykov
Post by Eliot Miranda
#exception is a pragma (and implemented as such) and affects the
semantics. The fact that the implementation hasn't caught up is
simply historical. CPOK was introduced before we hit on a regular
implementation scheme for pragmas, at a time when for example the
primitive: pragma was implemented by bits in a method header or
specific bytecodes. If we had to do it over I think we'd be much more
regular, and all primitive: C: et al methods would answer pragma
messages, and we'd write <primitive: 123 errorCode: aTemp> as
<primitive: 123 errorCode: #aTemp>
or
<primitive: 123 errorCode: 'aTemp'>.
At least that's my take on it.
We _would_ be regular, but we are not. primitive: is still implemented
by specific bytecodes, produces a regular CompiledMethod, and is not
visible when asking for a method's #attributes. Ditto for C:.
And so it does for the unwind methods. Its OK for there to be extra
stuff generated from the pragma. But we need all pragmas to be
accessible as pragmas. Right now primitive:[errorCode:] and C: don't
fit. I think everything else does.
Post by Vassili Bykov
The disagreement is about terminology (or separating intention from
implementation :-). I see how much more attractive it would be to
consider C: and primitive: as pragmas like others, and say pragmas are
anything within angle brackets. Indeed I would prefer to have them that
way. But I can't seriously consider them as such until I can do
Pragma allNamed: #primitive:errorCode: from: Foo to: Object
and use the usual interface of Pragma to reflect on the results.
#primitive: wouldn't be that hard to fit into this common Pragma scheme,
but #primitive:errorCode: might be trickier, and C: even more so with
its silly pseudo-C syntax.
We should definitely do this. We have backward compatibility issues
with both primitive:errorCode: and C: but these are probably minor (i.e.
we can provide auto correct on file-in and parcel load).
--
_______________,,,^..^,,,____________________________
Eliot Miranda Smalltalk - Scene not herd
Vassili Bykov
2004-10-29 19:42:56 UTC
Permalink
Post by Eliot Miranda
Post by Vassili Bykov
Call me a language lawyer, but in that case I am waiting to see BNF of
our syntax that describes things like
<C: DWORD CommDlgExtendedError(void) >
Right. But you'd have no problem with
<C: 'WORD CommDlgExtendedError(void)'>
would you? And being able to get the type string from the pragma
instead of having to parse the method source would be useful also.
If we are free to fantasize, I would prefer to toss pseudo-C entirely
and have something like

<function: 'CommDlgExtendedError'
parameterTypes: #()
returnType: 'WORD'> "or #WORD"

IMHO CPOK didn't get it quite right. It uses pseudo-C syntax in methods,
which is cute but has no real advantages and some disadvantages compared
to structured pragmas like the above. Yet it doesn't support C syntax
faithfully enough where it matters: having a .h parser that would handle
complex real-world header files.
--
Vassili Bykov
Tools Technical Lead, VisualWorks Engineering
v b y k o v A T c i n c o m D O T c o m
http://www.cincomsmalltalk.com/userblogs/vbykov
Eliot Miranda
2004-10-28 21:06:57 UTC
Permalink
Post by Andrei N.Sobchuck
When pragmas where introduced?
Well, I think of pragmas being introduced back in Smalltalk 80 (or
possibly earlier). The first pragma was
<primitive: N>

In ObjectWorks 2.5 this was extended with
<primitive: N errorCode: errorCodeTempVar>

In VisualWorks 1.0 (or possibly ObjectWorks 4.x) another pragma was
introduced:
<resource: #symbol>
used for marking methods defining "resources" such as GUI and Menu specs.

CPOK, the C programmer's Object Kit, which was introduced somewhere
around the same time (before my time at ParcPlace) introduced another:
<C: c typedef or define>

Then in the run-up to VisualWorks 2.5 I joined ParcPlace and was
offended by the mechanism by which the unwind-protect methods
valueNowOrOnUnwindDo: and valueOnUnwindDo: [thankfully now renamed ;) ]
were marked for unwind. The class side of BlockClosure implemented
#validateMethod:forSelector:, which was a hook sent on installing a
method into a method dictionary, provided for just this purpose. The
method checked for the selector being either valueNowOrOnUnwindDo: or
valueOnUnwindDo: and marked the methods appropriately. I found it an
egregious hack. After all one could have redefined the method selectors
to be anything and the system would still have attempted to mark them as
unwinds. The semantics had been moved to something related to the
selectors, not the methods themselves.

So I decided the methods should use a pragma:
<exception: #unwind>
and Steve Dahl generalized the scheme such that all the above could be
considered pragmas, i.e. messages with literal arguments that could be
associated with methods and queried. We used them for unwinds and
exception handlers.

Then in the run-up to VW 3.0 I hit on the idea of menu pragmas, where
menus could be composed from methods that included menu pragmas, and
hence adding a method with a pragma could immediately extend a menu
without having to rebuild it. But the real motivation was to avoid menu
definition conflicts when different parcels needed to extend the same
menu with different methods. Menu pragmas allowed one to avoid writing
a menu spec for the extended menu, and hence avoided having to resolve
the conflicts between different extended specs.
Post by Andrei N.Sobchuck
What was the purpose?
Whatever you want. They're useful in attaching meta data to a method
such as "this method is an action method on a particular menu" or "this
method has exotic execution semantics". One of my favourite uses is in
marking COM server methods, invented by Tami Lee. One adds the COM
signature of a method one wants to export to the method as a pragma and
then runs a wizard which generates all the COM type machinery to
actually export the interface to COM. Another is Vassili's part-whole
framework for dialog composition in vw7.2.

But my favourite one is Steve Dahl's invention for resolving conflicts
between different systems that need to add pragmas. Our first idea with
pragmas in 3.0 was that anyone should be able to add their own pragmas,
and the first person other than Steve and I was Tami with her COM
interface scheme. We needed a way of specifying which pragmas a class
would compile because we thought it was safer being able to specify a
particular set than compiling any old pragma. Otherwise how would one
spot speeling errors like
<primtive: N>
?

In the first general implementation we required classes to define a
pragmaKeywords method to answer an array of pragma selectors. The
problem was exactly analogous to menu spec conflicts. If two different
parcels tried to extend the same class with different sets of pragma
keywords they'd conflict. So Steve invented the pragma pragma. If you
want to add pragmas you define a class side method with whatever
selector you want which answers a literal array of pragma methods and uses
<pragmas: #instance>
and/or
<pragmas: #class>
to specify whether the pragmas are legal in class and/or instance side
methods.

Look at senders of #pragmas:.

The best thing about pragmas is their implementation as Message
instances. So one can do senders and implementors on them, and process
them by performing them. For example, menus get built by sending the
actual menu pragma message to a MenuAutomaticGenerator.
Post by Andrei N.Sobchuck
Do pragmas exist in other Smalltalk dialects?
As Vassili said, he did an implementation for Squeak. David Simmons has
done similar stuff in AOS and S#, but VW's pragmas are "just" messages
with literal arguments, whereas his are I think more general XML
annotations.
--
_______________,,,^..^,,,____________________________
Eliot Miranda Smalltalk - Scene not herd
Paolo Bonzini
2004-11-02 12:38:54 UTC
Permalink
Thanks for the very enlightening history!
Post by Eliot Miranda
Post by Andrei N.Sobchuck
Do pragmas exist in other Smalltalk dialects?
As Vassili said, he did an implementation for Squeak. David Simmons has
done similar stuff in AOS and S#, but VW's pragmas are "just" messages
with literal arguments, whereas his are I think more general XML
annotations.
I have added pragmas to GNU Smalltalk too. Pragmas are called
"annotations" in GNU Smalltalk; there is no pragmas pragma at least
for now. They are a great addition at least in system code and I'm
happy of having mutuated them from VW together with ephemerons.

They're in the current beta releases 2.1x (where x is a letter from a
to g, with 2.1g released today featuring a Gtk+ browser -- shameless
plug). My first usage was to simplify exception handling (in my case
I am also using them to avoid special-casing selector names like
#on:do:), but in a more pluggable way than VisualWorks.

I supply a BlockClosure in the pragma which tells the
exception-handling machinery about the exceptions that a particular
context can catch): I've used this to implement Java exception
handlers, with handlers interspersed with the containing methods'
bytecodes and without search for an "optimal" exception handler (in
#on:do: you can specify a subclass after the superclass, while in Java
your handler would not be executed). GNU Smalltalk implements
unwinding differently (in the VM, with a special primitive), so
there's no need for the <exception: #unwind> pragma there.
Vassili Bykov
2004-11-02 15:39:05 UTC
Permalink
Post by Paolo Bonzini
I supply a BlockClosure in the pragma which tells the
exception-handling machinery about the exceptions that a particular
context can catch): [...]
This is interesting. What is the scope of such closures?

--Vassili

Loading...