On 5 February 2015 at 21:20, Thierry Goubier <[email protected]> wrote: > > > 2015-02-05 21:28 GMT+01:00 Eliot Miranda <[email protected]>: >> >> >> >> 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. > > > 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. Eliot's point is that pragmas _describe_, and then other systems act on those descriptions. 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. 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
