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

Reply via email to