2015-02-07 20:48 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com>:
Array literals are not executable. They are literals. They need an interpreter to add semantics. This is one of the reasons why Spec is poor. Pragmas are Message instances. They respond to sendTo:/sentTo:. STON is not executable, it needs an interpreter.
The STON thing was a joke on the tagging use of pragmas :)
There are other ways to add metadata to methods. Without tagging.
Haven't we discussed that? Putting metadata off to the side introduces a bookkeeping problem. It is a bad idea.
And pragmas only partially address that.
Partially? It completely solves the issue of keeping metadata associated with a method.
It solve the issue of associating a limited form of metadata (one or two pragmas), with a few drawbacks (see below).
Imagine that Sista works, that it has dozens of tuning points for a method
(int, no recurse, vect, is a reduce, openCL, thread-safe, hot point, this loop should be enrolled) do you imagine writing all that into the method to guide Sista with pragmas? You'll end up in exactly the same situation as OpenMP 4, where it is possible to write programs with more #pragma lines than C/C++ code.
One doesn't need a line per option. One can use... literal arrays someImportantMethod <sistaTuningHints: #(threadSafe unroll)> but for Sista we imagine very few tuning options, perhaps only one, which is to say to the optimizer optimize this method even if it doesn't show up as a hot spot. Sista is /not/ going to look like gcc.
Hum, that's sad. I wanted to try a few ideas along the ones I see in the HPC projects I'm on: specialisation, vectorisation, accelerator off-loading :(
The method with the menu pragma is named "worldMenuCommand" ...
I don't see examples of this in the pharo 4 image I have to hand. What's the full selector?
Search for menu pragmas with the finder; the first two in Pharo30 are: RecentMessageList>>recentMessageListMenuOn: ScriptLoader30>>menuCommandOn: (I just made the worldMenuCommand up :)) The tag is<worldMenu>, so it is strictly descriptive.
The method with the gtInspector pragma is named "gtInspectorPresentation..."
This one is ok. The pragma both says the method is a pane in a glamour inspector, and says what the order is relative to others. One thing that's broken is that the finder doesn't find any senders. Another thing is that the pragma doesn't do anything. If the Glamour inspector added panes to itself by using sentTo: to evaluate the pragma then when you did "implementors" you'd find the builder.
Ok. We're starting to get somewhere, with a better idea of what the semantic of pragmas should be. And closer to what I said earlier: make pragmas executed at compile time.
So those examples are not taking full advantage. In VW they're more interesting, e.g. searchForStringInSource "Spawn a Browser on all methods which contain a specified string."
<menuItem: #(#MethodsWithPhraseDot #menus 'Methods with &Phrase...') nameKey: nil menu: #(#listMenu #browse) position: 21.03 > ...
In a way, I like this usage: it's clear, it will be executed. In another way, yuck :( You're doing an OpenMP 4 kind of pragma (writing programs in the pragma syntax), forcing us to program in a pure literal dialect of smalltalk :(
which says which sub menu it is in (listMenu browse), where it is relative to other entries (21.03), what its hot key is (P). And MenuAutomaticGeneraotr implements the pragma (which shows up though the "implementors" menu on the menu pragma method): menuItem: label nameKey: key menu: menuIDs position: position "If the method is to be inserted into our menu, create a MenuItem, otherwise answer nil." | realLabel | menuIDs first = menuName ifFalse: [^nil]. realLabel := self decodeLabel: label. ^Array with: ((MenuItem labeled: realLabel) nameKey: key) with: (menuIDs copyFrom: 2 to: menuIDs size) with: position
Additionally, as I told you before: the pragma semantic isn't in the method... It's somewhere else in the system and senders of that pragma doesn't get it.
I know that very well. If things are done right, that the finder will find pragmas via "senders", and if the designer has chosen to implement the pragma in some processing object, then the link is made. But I disagree that the semantic is entirely elsewhere in the system. The /implementation/ is elsewhere in the system. The semantic is in the pragma, in exactly the same way as a message specifies an operation to be performed and a method specifies an implementation, because... pragmas are messages.
But they can (and often are) used in a strictly descriptive way because they do not carry any clear semantic in Smalltalk itself.
Just have a look at OmniBrowser and tell me that you don't understand where the menu commands are :)
I don't want to criticise OmniBrowser, but if pragmas are used in the pattern above those relationships become clear.
You can't write full command objects the way you describe (with a single method and pragmas) because: command objects can inherit, they can have mutiple aspects (menu item, shortcut in window, key in menu, activation conditions). Pragmas are a solution if your commands are simple (lightweight command objects) and pragmas can't inherit if they are complex (nor can they use utility methods or complex processing, since they are literal messages). Thanks for all the explanations, this was enlightening :) I'll probably have a look at how I use pragmas in AltBrowser command objects; now those are: clipboardCommands <textAreaCommand> ^ #(#AltCutTextCommand #AltCopyTextCommand #AltPasteTextCommand #AltSelectAllTextCommand) and, with your suggestions, it would become: clipboardCommands <textAreaCommands: #(#AltCutTextCommand #AltCopyTextCommand #AltPasteTextCommand #AltSelectAllTextCommand)> But I stay as strongly against them as before (probably even more: I didn't understand fully how nasty(*) considering them executable would be). I want a better solution :) Happy to disagree :) Thierry (*) i.e. similar to C pragmas