Hi Frank,

On Fri, Feb 6, 2015 at 2:29 AM, Frank Shearar <frank.shea...@gmail.com>
wrote:

> On 5 February 2015 at 21:20, Thierry Goubier <thierry.goub...@gmail.com>
> wrote:
> >
> >
> > 2015-02-05 21:28 GMT+01:00 Eliot Miranda <eliot.mira...@gmail.com>:
> >>
> >>
> >>
> >> On Thu, Feb 5, 2015 at 11:34 AM, Thierry Goubier
> >> <thierry.goub...@gmail.com> wrote:
> >>>
> >>>
> >>>
> >>> 2015-02-05 18:51 GMT+01:00 Eliot Miranda <eliot.mira...@gmail.com>:
> >>>>
> >>>>
> >>>>
> >>>> On Thu, Feb 5, 2015 at 2:31 AM, Thierry Goubier
> >>>> <thierry.goub...@gmail.com> wrote:
> >>>>>
> >>>>>
> >>>>>
> >>>>> 2015-02-05 10:55 GMT+01:00 Sven Van Caekenberghe <s...@stfx.eu>:
> >>>>>>
> >>>>>> 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.
> >
> >
> > I don't contest the possibilities, it's just that they add a significant
> > layer of complexity when non mastered (how many Pharo developpers know
> which
> > event you have to register to to receive all new methods notifications?
> Is
> > that documented in one of the books?), and that, except for using them as
> > <primitives> or for extensibility, I see other syntaxes and smalltalk
> code
> > which are simpler.
> >
> > A good example is that the pragma syntax is never included in the one
> page
> > Smalltalk syntax description :)
> >
> >>
> >>
> >>>
> >>>
> >>>>
> >>>> (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.
> >
> >
> > I agree with the "metadata", but I'd prefer a executable, evaluate that
> > block as a medata literal than the pragma. Something that says
> > "onceAndStoreAsMetadata", to a block, for example. An API to compiled
> > methods which says add metadata.
> >
> > I strongly agree with your keep it in sync argument, still. Pragmas are
> > better than nothing.
> >
> >>
> >>
> >> 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.
> >
> >
> > Just a naming convention does just that perfectly fine, and with less
> lines
> > (except for extensions by external packages) and faster code in many
> cases.
> >
> >>
> >>
> >> 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 ;-).
> >
> >
> > Ok, I start to see where the abstraction wasn't working so well... since
> > pragmas are not executed, when writing a method you can't know if the
> pragma
> > is correct, because even executing the method may not trigger the pragma
> > induced code. So you need the legalPragmas to give metadata on metadata
> for
> > the compiler to do a bit of static checking, but it doesn't work for
> > system-wide pragmas unless you extend Object :(
> >
> > And often it doesn't matter if the pragma reference a completely non
> > existent method or api, since it is probably never executed by anybody
> (and
> > if it is, it won't probably reify the error message properly as a
> > compilation error as it should, because it may be triggered miles away
> from
> > the system browser).
>
> Pragmas don't execute. They're _data_. There is no "calls unknown
> sender" because the don't execute.
>

I think they can do both, which is nice.  I actually prefer uses of pragmas
where they /are/ executable.  They ca be performed by some object, and that
execution can modify the system in the desired way, for example having a
menu builder perform the menu definition pragma in a menu action method to
add that action to a menu.


> Eliot's point is that pragmas _describe_, and then other systems act
> on those descriptions.
>

Right.  But that description is executable by something else.  Unlike, for
example, a block as metadata which is only executable.


> They're just like Java or C# attributes, or Python decorators. Only
> they're better, because Java/C# attributes can do anything, whereas
> pragmas merely describe.
>

Are you sure Java and C# attributes are executable?  When I read the
wikipedia page for Java attributes I get the notion that they're structured
non-executable data, i.e.:

"When Java source code is compiled, annotations can be processed by
compiler plug-ins called annotation processors. Processors can produce
informational messages or create additional Java source files or resources,
which in turn may be compiled and processed, and also modify the annotated
code itself. The Java compiler conditionally stores annotation metadata in
the class files, if the annotation has aRetentionPolicy of CLASS or
RUNTIME. Later, the JVM or other programs can look for the metadata to
determine how to interact with the program elements or change their
behavior.

In addition to processing an annotation using an annotation processor, a
Java programmer can write their own code that uses reflections to process
the annotation. Java SE 5 supports a new interface that is defined in the
java.lang.reflect package. This package contains the interface called
AnnotatedElement that is implemented by the Java reflection classes
including Class, Constructor, Field,Method, and Package. The
implementations of this interface are used to represent an annotated
element of the program currently running in the Java Virtual Machine. This
interface allows annotations to be read reflectively."

The microsoft doc on C# indicates that they're declarative, but no mention
of those declarations being executable:
"C# enables programmers to invent new kinds of declarative information,
called attributes. Programmers can then attach attributes to various
program entities, and retrieve attribute information in a run-time
environment. For instance, a framework might define a HelpAttribute
attribute that can be placed on certain program elements (such as classes
and methods) to provide a mapping from those program elements to their
documentation."


> frank
>
> >> 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
> >
> >
> > Yes, and I can point out some of its shortcomings: it's non-obvious, it's
> > limited, tools, even that many years later don't support them well (in
> > Squeak or Pharo, at least), its redundant in quite a few variants.
> >
> > Please, could we improve a bit? Methods belonging to multiple protocols
> > would give us the same decoupling as pragmas, and I would be free to
> avoid
> > them where I shouldn't have to use them :)
> >
> >>
> >>
> >> 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.
> >
> >
> > That would certainly be interesting :)
> >
> >>
> >>
> >>>
> >>>
> >>> 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.
> >
> >
> > Yes!
> >
> > Thanks for taking the time to argument,
> >
> > Thierry
> >
> >>
> >>
> >>
> >> --
> >> best,
> >> Eliot
>
>


-- 
best,
Eliot

Reply via email to