On Thu, Feb 5, 2015 at 11:34 AM, Thierry Goubier <[email protected]>
wrote:

>
>
> 2015-02-05 18:51 GMT+01:00 Eliot Miranda <[email protected]>:
>
>>
>>
>> On Thu, Feb 5, 2015 at 2:31 AM, Thierry Goubier <
>> [email protected]> wrote:
>>
>>>
>>>
>>> 2015-02-05 10:55 GMT+01:00 Sven Van Caekenberghe <[email protected]>:
>>>
>>>> It is obviously a compromise (or a continuum) between abstractions and
>>>> performance.
>>>>
>>>
>>> I agree. With a special view in that we are in a sub domain where simple
>>> things well designed (Smalltalk, that is) are amazingly good at supporting
>>> complex designs.
>>>
>>>
>>>>
>>>> But there should remain a focus on efficiency (not just speed but also
>>>> memory), it is hard to fix these things years later.
>>>>
>>>
>>> And I like the fact that efficient code and design is often a pleasure
>>> to read and learn from :)
>>>
>>> Now, being radical: could we get rid of pragmas ? The only reason I see
>>> to them is that they allow extension by external packages, because we can't
>>> have methods which belong to two protocols (*).
>>>
>>
>> They are a Smalltalk-centric way of adding arbitrary metadata to methods;
>> Smalltalk-centric in that a pragma is a Message instance, may be queried
>> for senders, performed, etc, and that it can be parsed using the standard
>> compiler (they add no new syntax).  They have been broadly used.  IME they
>> have simplified and reduced code where ever they have been used.  They
>> don't have to be there but they're a good thing.  Why do you want to get
>> rid of them?
>>
>
> Because the "they have simplified and reduced code where ever they have
> been used" is wrong. I just have to give you a counter example:
>

OK, the claim is too strong.  But they /have/ simplified code in cases
where they're appropriate.  And I can cite several examples.


>
> One of the uses of pragmas is associating methods containing Gui commands
> or settings to specific objects. Based on an object inspected or selected,
> you search among all its methods the ones containing a specific pragma (and
> you order them by a parameter to that pragma, if you want), and you execute
> that method to retrieve the objects you want (presentations, menu commands,
> shortcuts, you name it, I use it :)).
>
> The code to do that is exactly as long as the one which, on the same
> object, retrieve all methods under a certain protocol (the latter being
> faster than the pragma one, to boot).
>
> Each method is one line longer ("the pragma").
>
> Each such method usually has in its name a copy of the pragma
> (gtInspectorXXX methods, I'm looking at you), because of course this is far
> more user friendly to indicate its purpose in the method name than in only
> the pragma.
>
> (There are two more arguments for the use of pragmas in that context, one
> which has a direct counter-example, one which hasn't: )
>
> Moreover, the semantic of pragmas is "interesting" to describe, and in
> some cases, require a good amount of dark magic about a global object
> listening to all methods changes and capturing (and executing) certain
> methods in a vague relation about when this is going to happen, or being
> triggered on specific system events (main menu rebuilding, anyone?). The
> funny thing is to see that pattern visible on a profile when loading
> packages (talk of a scalable approach).
>

But triggering in the background happens for maintaining change sets,
notifying other clients too.  It's not as if pragmas introduced such
triggering; that kind of triggering has been in use for a long time.  And
being able to reshape the GUI automatically is very useful.


>
>
>> (and yes, I'm biassed)
>>
>
> Then you're the right person to give me counter arguments...
>
> (Now, I'd look differently at pragmas used for gradual typing and so on...
> But even for something like FFI, I'd seriously prefer to have Smalltalk
> calls to describe the call and its arguments than a kind of script hidden
> inside pragmas, just for the discoverability and because it makes one less
> idiom to deal with)
>

Why?  A good use of pragmas is to associate meta data with a particular
method.  Having calls off to the side always introduces the need for
book-keeping to keep those methods off to the side in sync with the methods
they're describing.  Typically everyone rolls their own.  But here we're
adding a level of triggering just to keep the metadata methods in sync.

There is no such need with pragmas; they are always in sync with the
methods they describe because they are embedded in their methods.  Instead
we can use triggering to do useful things, adding a pane to open inspectors
as soon as we define the method that describes the pane, adding or removing
a menu entry, etc.

This is one idiom that covers a host of other cases.  That's why I claim
that whenever I've seen it used it has reduced complexity.

Some history.  Steve Dahl, I developed pragmas at ParcPlace, with Vassili
Bykov adding abstractions for accessing them.  The first step was to
replace some ugly class-side code to set unwind bits in ensure: and
ifCurtailed: by a pragma the compiler would recognise and set the bits
itself.  The first real use was to make the VisualWorks launcher's menus
extensible.  Before pragmas the launcher's menu was static and had lots of
disabled entries for launching tools that were sold separately such as
DLLAndCConnect.  With pragmas the launcher's menu was defined with the base
system's tools and then extended as each tool package was loaded, or
cut-back as each tool was unloaded.  So that decoupled the launcher from
introducing new tools.  A nice result.

We then started using it for the browser and one could plug-in a single
tool without redefining the browser's menu methods, which decoupled each
extension.  All this was done in the context of the parcel system, where we
could rapidly load packages (parcels ~= Fuel).  Pragmas allowed us to
decouple these tools where they collided in places like menu definition,
tool registration.

Then Tami Lee, who was managing the COM connection that turned a VW image
into a COM server, became the first "user" of pragmas outside of myself and
Steve. She used it to replace a lot of class-side methods that defined the
signatures of methods that comprised the server.  It was a lovely
clean-up.  One could define the COM signature for a method in the method
itself, and the class side lost about three separate methods that defined
all that metadata.  One could read the server method itself and understand
its semantics without having to consult the class-side methods.  One didn't
have to know that there was metadata hidden on the class side because it
was right there in your face.

Then Vassili used it for his cool inspector framework, Trippy, which was
similar to Glamour in some ways, and was a huge improvement over the old
Inspector framework, again resulting in a much more pluggable, decoupled
and extensible system.  Vassili also added the abstractions for accessing
pragmas in methods.

Then we added checking so that one could restrict the compiler to accept
only legal pragmas for a given class.  But if we defined the legal pragmas
in a class-side method, say legalPragmas, then this would be exactly the
kind of single point for extensions that causes collisions between
packages, each of which might want to add its own set of pragmas.  The
solution... use a pragma to mark a class-side method as defining a set of
legal pragmas for a class.  One could have more than one method defining a
set of legal pragmas; packages wishing to add their own cool pragmas were
decoupled.  Once the system because recursive, it had to be a good idea ;-).

There are other uses; you've seen them.  I used them in VMMaker to
eliminate metadata that was embedded as sends to methods defined as ^self
that Slang had to extract and analyse, and filter-out from generated code.
They simplified Slang's code anaylsis, made the simulator more efficient
(since there were no longer sends to execute).  My point is that in all the
cases I've seen, using pragmas has
- simplified the code
- made it obvious that methods have metadata associated with them
- replaced specialized ways of associating metadata with code by the
general pragma mechanism
and in many of the cases it has
- provided a more decoupled system
- provided a more dynamic and extensible system

I've been meaning to write up the history of pragmas for ages, but Vassili,
Steve or I have always been too busy.  I think a community paper on their
use and history would be worth-while, and might go a long way to reduce
antipathies like yours.  I will forever be in debt to anyone who wants to
volunteer to help me write such a paper.


>
> Thierry
>
> (Look. I started using Smalltalk in 1992... and up to your description, I
> wasn't aware pragmas were supposed to follow message syntax ;) Thanks for
> the explanation, by the way)
>

They /have/ to follow literal message syntax.  t's all the compiler will
accept.  That's why there needs to be a paper.


-- 
best,
Eliot

Reply via email to