On Fri, Feb 6, 2015 at 5:58 PM, Thierry Goubier <[email protected]> wrote:
> Hi Eliot, > > maybe I'll frame the core question a bit differently, thanks to your > explanations. > > I see pragmas used mainly for two things: > > 1- expressing a link to some metadata used by low level tools: compiler, C > lang generator, etc... primitives for me are part of that. Kind of neat to > see that unified. > btw, I just used a pragma to solve this issue of getting correct debugger behaviour for halting and stepping over #halt statements [1]. There seem about a dozen methods that can cause a #halt spread between Object and Halt classes which should all behave similarly, so the options would seem * hardcode all these methods either into to check for in Halt>>signalerContext (or into a helper method called from #singalerContext) * have a convention for a certain protocol to hold these methods, which Halt>>signalerContext can look up (except currently the methods on Object are an extension protocol) * tag each such method with a pragma. This simplified the solution a lot. The search of the call stack just asked each method if it had the <debuggerCompleteToSender> pragma. > 2- categorizing things in a decoupled, package-extension compatible way. > > I still think there is something in the design that bother me. 1- and 2- > are convention-based, so as is most of Smalltalk anyway, so diregarding > another approach to 2- as convention-based is a bit dishonest: pragmas get > more authority because they look like they have been integrated in the > language definition compared to competing solutions. > > No, this is just because I start to wonder if methods shouldn't have a bit > more in that "define, add and manipulate" metadata idea, i.e. make it more > explicit and start to have tools which represent methods as more like > objects and not only text items (methods having metadata, additional slots > or instance variables, counters, statistics, ast, traces, break points, > etc...). And, in a way, a need to have two levels of execution: one which > happens at compile time (i.e. when one accept a method), one which happens > at runtime. > > For that, I think pragmas are a start, but they are not the complete > answer. And I think we should solve the package-extension compatible thing > in 2- to not have 2- (which is just for me a plain categorisation issue) > polluting the design by introducing additional/unrelated requirements. > > > > 2015-02-05 22:47 GMT+01:00 Eliot Miranda <[email protected]>: > >> Hi Thierry, >> >> A block is far more difficult to deal with than a pragma. A pragma has a >> simple key, its selector, and simple access to its arameters, the >> arguments. A block is opaque. Essentially it can only be executable. >> Pragmas are both executable and function as annotations. >> > > Pragmas are executable, but in a context which is not visible at the place > they are written. > > >> >> >> >>> 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. >>> >> >> Yes, but there end up being lots of naming conventions and they are >> non-obvious. Whereas pragmas, because they are in-your-face in the methods >> in question, don't need conventions. They just need documenting ;-). >> > > They are still conventions which needs documentation. Pragmas are, in > allmost all uses, indirections (i.e. a tag meaning something to a far away > object), and the meaning associated to a pragma is, in every case, a > roll-your-own solution. And they are clearly "in your face" :) > > >> >> >> That's not necessarily true. Some pragmas do cause processing at compile >> time. For example, an FFI signature pragma can be checked at >> compile-time. But it's in keeping with smalltalk that type checking is not >> performed at compile time in most cases, isn't it? Why should one require >> that pragmas be semantically checked at compile time when normal SMalltalk >> code isn't? At least one knows that the message instance the pragma is >> compiled to is a valid object and *can* be performed. So pone does know at >> least that the pragma is executable. Obviously whether that ability to be >> executed only becomes potent with the right receiver. So any compiled >> pragma as the potential to be usefully evaluated. >> > > Ok, but its all fuzzy. > > It may be executed, but it may be not. > > It may send an error if incorrect, but it may fail silently. > > It may be executed at compile time, it may be executed sometime later > triggered by the compilation, or it may be executed at runtime, as if it > was normal code. And of course it may not be executed at all ... > > You see what I mean? > > >> >> 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). >>> >> >> >> There is lots about Smalltalk that is non-obvious, about programming in >> general that is non-obvious. I don't see that as a specific criticism of >> pragmas. Once one knows the idiom it is easy to use; its wide-spread use >> is evidence of that. And hopefully this conversation will help make it >> more obvious :-). That it is limited is also not perhaps a useful >> criticism. The issue is whether it is adequate. I think it is. A literal >> message goes a long way. I'e not heard of complaints about limitations so >> far. Do you have specific examples where pragmas are inadequate? The >> tools /do/ support them. One can do senders and implementors in the >> browser and see the methods that include them, and the implementors of >> pragmas. browseAllSelect: will narrow down the search. There is an API >> for programmatic use (pragmasDo: et al). >> > > See [*][**] for the tools support. For me, pragmas, even in their > definition, have serious semantic issues. If they were strictly, as you > describe them, a metadata API access executed at compile time, then they > would be a lot stronger. > > Make them sent at compile-time on the method object, and that would > probably solve all the true arguments I have against them :) > > for example: <worldMenu> against <tagAndAnnounce: #worldMenu>; <tag: > #gtInspectorExtension> instead of <gtInspectorExtension>, etc... > > (<tagAndAnnounce:> would gain a bit of performance, as well). > > Thierry > > [*] Searching a bit for menu pragmas in a Pharo image seems to return a > bit of a mess. There is so many of them, all differents, and interestingly, > this does not return the code triggered (or using) them, which makes > discovery of what the pragma is used for (and its parameters) an > 'interesting' problem. > I think discoverability is an issue with pragmas. From Nautilus you can't "see" which methods contain which pragmas. I wonder if one solution for this would be for pramga methods to be grouped under a <virtual-protocol> in the third pane of Nautilus. [1] https://pharo.fogbugz.com/default.asp?12970 cheers -ben > > I suggest a task then: an illustrated sequence of how to search for the > code triggering world menu addition of a new command, for someone which is > new to Pharo ;) > > [**] even when used for categorisation, the API is prone to bugs, such as > having a method without pragma overriding a superclass method with pragma > because they have the same name. > >
