2015-02-08 19:46 GMT-03:00 Eliot Miranda <[email protected]>: > > > On Sun, Feb 8, 2015 at 1:26 PM, Hernán Morales Durand < > [email protected]> wrote: > >> Hi Eliot, >> >> 2015-02-08 12:50 GMT-03:00 Eliot Miranda <[email protected]>: >> >>> Hi Hernan, >>> >>> >>> On Feb 7, 2015, at 12:55 PM, Hernán Morales Durand < >>> [email protected]> wrote: >>> >>> Hi Eliot, >>> >>> 2015-02-07 14:48 GMT-03:00 Eliot Miranda <[email protected]>: >>> >>>> Hi Hernan, >>>> >>>> On Sat, Feb 7, 2015 at 7:41 AM, Hernán Morales Durand < >>>> [email protected]> wrote: >>>> >>>>> >>>>> 2015-02-07 5:59 GMT-03:00 kilon alios <[email protected]>: >>>>> >>>>>> Personally I don't like Pragmas, they have not convinced me so far >>>>>> that they fit the style of Smalltalk syntax. I have to confess though I >>>>>> never liked descriptive elements and languages . >>>>>> >>>>>> >>>>> Me neither. Actually the pragma idea is not wrong per se, it is the >>>>> tag syntax to write them which bothers me. Because the world can be >>>>> described with tags if you start that path. >>>>> >>>> >>>> How exactly is the syntax wrong? >>>> >>> >>> I am not saying syntax is wrong, I just don't like it because: >>> >>> 1) Adds another level of representation inside an already reflective >>> system. >>> >>> >>> What do you mean exactly? I don't have clear recollection of whether >>> they were in Squeak in 08 or if I ported then, but at that time >>> CompiledMethod had a properties object, and pragmas were merged into this. >>> What I did do was save a lot of space getting rid if the properties object >>> unless a method needed it. And IIRC I changed the implementing class from >>> MethodProperties to AdditionalMethodState. So there was no additional >>> level of representation. a) the syntax was already there fir primitives >>> and b) the state was already there in methods. >>> >>> >> The place where pragmas are located internally are not an issue for me. >> The fact that special tags are not following the message pattern template >> is. It says there is a special collector, parser, validator, etc. a whole >> mechanism because something is - supposedly - not easily expressible with >> plain reflective messages. >> > > I don't understand. Pragmas are literal message patterns, period. There > is an exception for the primitive pragma so that the variable name for a > primitive's error code can be introduced, but that's part of primitive > parsing, not general pragma parsing. At least in Squeak here's the code: > > Parser>>pragmaSequence > "Parse a sequence of method pragmas." > [ > (self matchToken: #<) > ifFalse: [ ^ self ]. > self pragmaStatement. > (self matchToken: #>) > ifFalse: [ ^ self expected: '>' ] ] repeat > > pragmaStatement > "Read a single pragma statement. Parse all generic pragmas in the form of: > <key1: val1 key2: val2 ...> and remember them, including primitives." > | selector arguments words index keyword | > (hereType = #keyword or: [ hereType = #word or: [ hereType = #binary ] ]) > ifFalse: [ ^ self expected: 'pragma declaration' ]. > > " This is a ugly hack into the compiler of the FFI package. FFI should be > changed to use propre pragmas that can be parsed with the code here. " > (here = #apicall: or: [ here = #cdecl: ]) > ifTrue: [ ^ self externalFunctionDeclaration ]. > > selector := String new. > arguments := OrderedCollection new. > words := OrderedCollection new. > [ hereType = #keyword or: [ (hereType = #word or: [ hereType = #binary ]) > and: [ selector isEmpty ] ] ] whileTrue: [ > index := self startOfNextToken + requestorOffset. > selector := selector , self advance. > words add: (index to: self endOfLastToken + requestorOffset). > (selector last = $: or: [ selector first isLetter not ]) > ifTrue: [ arguments add: (self pragmaLiteral: selector) ] ]. > selector numArgs ~= arguments size > ifTrue: [ ^ self expected: 'pragma argument' ]. > (Symbol hasInterned: selector > ifTrue: [ :value | keyword := value]) > ifFalse: [ > keyword := self > correctSelector: selector wordIntervals: words > exprInterval: (words first first to: words last last) > ifAbort: [ ^ self fail ] ]. > self addPragma: (Pragma keyword: keyword arguments: arguments asArray). > ^ true > > I can't speak for how its been implemented in Opal but I'd be surprised if > it is using separate machinery. The Squeak code above is different from > the normal message parsing precisely so that it can insist that arguments > are only literals (pragmaLiteral: above). > > Ok, I will stop here because I see contradictions and no way we can agree on them. Amazing code BTW.
> >> 2) It could be done with plain common message sends. >>> >>> >>> No it can't. Common sends are executable and we don't want pragmas >>> executed when the method is run, we want the pragma executed when the >>> method is added, or analysed. That was what was ugly about the use of plain >>> sends in e.f. VMMaker, that there had to be lots of empty implementations >>> of the messages used for metadata. >>> >> >>> So using normal sends >>> - prevents the metadata from being directly executed because executing >>> them when the method is run is wrong >>> - confuses meta level and normal level, putting them at the same level, >>> and hence... >>> - confusing for the programmer because its not obvious what's metadata >>> and what's a normal send >>> - makes analysis harder for the same reason >>> >>> >> We are talking about different worlds here. >> > > So let;s stop talking because I;m getting frustrated. I make a valid > point about the inability to use normal selectors and you ignore my point. > > >> Theoretically I could mark methods this way: >> >> (Pragma >> for: (ASTBlockClosure >> #value:) >> selector: #primitive: >> arguments: (Array with: 60)) addPragma. >> > >> So the annotations could be written with normal message sends. >> And they could be tool supported, so no one gets confused. >> > > So this is embedded in a method? So it gets evaluated every time the > method is executed? Surely you're not serious. > > Precisely that is what should happens behind the curtains. I cannot believe why is so hard to understand. > >> >>> 3) Should be (to me) "hidden" from method pane, and displayed by a >>> specific tool inside the system browser. >>> >>> >>> I disagree. I want to see the pragma. It has essential information >>> that shouldn't be hidden. I want to edit it easily. >>> >> >> I want to see and edit the pragma too, when I am really interested. Just >> like with the bytecodes. >> >> >>> And how can you in the one hand say it can be implemented as a normal >>> message send a d at the same time want it hidden? Be consistent :-) >>> >>> >> There is no inconsistency. I am saying they should be hidden from the >> method body. >> >> The method pane you see in the browser should be used to send messages to >> your modeling domain (which already imposes its own difficulty), not being >> exploited to add meta information where meta could belong to >> instrumentation analysis (lint, profiling) or UI building (keymap, menu) or >> whatever excuse found to add more tags. >> >> I wonder how one could refactor this method: >> >> Greetings>>helloWorld >> <year: 2015> >> <status: #toDo> >> <author: 'Hernán'> >> <scope: #private> >> >> <soapOperationName: #HelloWorld> >> <soapDocumentation: #'Returns Hello World'> >> <soapResult: #String> >> <soapStyle: #RPC> >> >> <rmiOperationName: #HelloWorld> >> <rmiDocumentation: #'Returns Hello World'> >> <rmiResult: #String> >> >> <asn1OperationName: #HelloWorld> >> <asn1Documentation: #'Returns Hello World'> >> <asn1Result: #UTF8String> >> >> <dcomOperationName: #HelloWorld> >> <dcomDocumentation: #'Returns Hello World'> >> <dcomResult: #String> >> >> ^'Hello World' >> > > Thus: > > first, date & author can be recovered from the method source via > timestamp, but if you want to separate the author of the text from the last > editor of the method then... > > Greetings>>helloWorld > <addDocPage: #Greetings year: 2015 status: #toDo author: 'Hernán' scope: > #private> > <soapOperation: #HelloWorld documentation: #'Returns Hello World' > resultType: > #String style: #RPC> > <rmiOperation: #HelloWorld documentation: #'Returns Hello World' > resultType: > #String> > <asn1OperationOperation: #HelloWorld documentation: #'Returns Hello > World' resultType:#UTF8String> > <dcomOperation: #HelloWorld documentation: #'Returns Hello World' > resultType: > #String> > > ^'Hello World' > > and then have implementations of e.g. > SoapInterfaceBuilder>>soapOperation:documentation:returnType:style:, > ASN1InterfaceBuilder>> asn1Operation:documentation:returnType:style:, > etc, that add the method to the interface they're building. > > So, assuming your interface methods are in a class hierarchy from > SomeSoapInterfaceSubclass up to SomeSoapInterfaceBaseClass building looks > like, e.g.: > > | builder | > builder := SoapInterfaceBuilder new. > (Pragma > allNamed: #soapOperation:documentation:returnType:style: > from: SomeSoapInterfaceSubclass > to: SomeSoapInterfaceBaseClass) do: > [:pragma| > builder method: pragma method. > pragma message sendTo: builder] > > But if you're able you'll do it just like this: > > Greetings>>helloWorld > <addDocPage: #Greetings year: 2015 status: #toDo author: 'Hernán' scope: > #private> > <externalOperation: #HelloWorld documentation: #'Returns Hello World' > resultType: #UTF8String style: #RPC> > > ^'Hello World' > > implement the same method in the various builders, and coerce UTF8String > to String in those that only handle simple notions of string type. > > Why on _earth_ are people writing 17 pragmas where I see only two? > > Not the point I wanted to address, but thanks for the example and answering the questions patiently Cheers, Hernán
