LearningObject

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

LearningObject

stepharo
Hi guys

I'm on holidays (no book no mooc no bugs just playing magic good music
and hacking a bit)
and I wanted to implemented a fun object that learn from Object by
copying the methods.

ProtoObject subclass: #ATMinimalLearningObject
     instanceVariableNames: ''
     classVariableNames: ''
     package: 'MiniActalk2'


ATMinimalLearningObject >> doesNotUnderstand: aMessage

     | sel |
     sel := aMessage selector.
     Transcript show: 'Does not understand ',  sel printString ; cr.
     ^ (Object includesSelector: sel)
         ifTrue: [
                 self addFromObjectSelector: sel.
                 aMessage sendTo: self ]
         ifFalse: [ super doesNotUnderstand: aMessage ].

ATMinimalLearningObject >> addFromObjectSelector: aSelector

     | method |
     method := OpalCompiler new
                     class: self class;
                     source: (Object sourceCodeAt: aSelector);
                     compile.
     self class addSelector: aSelector withMethod: method.

ATMinimalLearningObject subclass: #ATProtozoid
     instanceVariableNames: 'ff'
     classVariableNames: ''
     package: 'MiniActalk2'


Now it is working but I have the impression that we may have a problem.

When I do
ATProtozoid new instVarAt: 1


I get the following definition for instVarAt:

instVarAt: t1
     self error: 'Decompilation failed'


but

Object sourceCodeAt: #instVarAt: returns the correct string.

  'instVarAt: index
     "Primitive. Answer a fixed variable in an object. The numbering of
the variables
      corresponds to the named instance variables, followed by the
indexed instance
      variables. Fail if the index is not an Integer or is not the index
of a fixed variable.
      Essential. See Object documentation whatIsAPrimitive."

     <primitive: 173 error: ec>
     self primitiveFailed'

May be the compile is not logging the method body.
But since the compiler is full uncommented this is super nice to learn
and get empowered.

Stef


Reply | Threaded
Open this post in threaded view
|

Re: LearningObject

Clément Béra
Hello,

The logging of sources is not part of the compiler. It is part of the behavior API. 

Something like that would work :

ATMinimalLearningObject >> addFromObjectSelector: aSelector
    self class compile: (Object >> aSelector) sourceCode classified: #foo

Now it is strange that the decompiler can't decompile instVarAt: . It looks like it is a bug related to primitive error code decompilation. This is something I should look at during the sprint...


2016-01-27 20:42 GMT+01:00 stepharo <[hidden email]>:
Hi guys

I'm on holidays (no book no mooc no bugs just playing magic good music and hacking a bit)
and I wanted to implemented a fun object that learn from Object by copying the methods.

ProtoObject subclass: #ATMinimalLearningObject
    instanceVariableNames: ''
    classVariableNames: ''
    package: 'MiniActalk2'


ATMinimalLearningObject >> doesNotUnderstand: aMessage

    | sel |
    sel := aMessage selector.
    Transcript show: 'Does not understand ',  sel printString ; cr.
    ^ (Object includesSelector: sel)
        ifTrue: [
                self addFromObjectSelector: sel.
                aMessage sendTo: self ]
        ifFalse: [ super doesNotUnderstand: aMessage ].

ATMinimalLearningObject >> addFromObjectSelector: aSelector

    | method |
    method := OpalCompiler new
                    class: self class;
                    source: (Object sourceCodeAt: aSelector);
                    compile.
    self class addSelector: aSelector withMethod: method.

ATMinimalLearningObject subclass: #ATProtozoid
    instanceVariableNames: 'ff'
    classVariableNames: ''
    package: 'MiniActalk2'


Now it is working but I have the impression that we may have a problem.

When I do
ATProtozoid new instVarAt: 1


I get the following definition for instVarAt:

instVarAt: t1
    self error: 'Decompilation failed'


but

Object sourceCodeAt: #instVarAt: returns the correct string.

 'instVarAt: index
    "Primitive. Answer a fixed variable in an object. The numbering of the variables
     corresponds to the named instance variables, followed by the indexed instance
     variables. Fail if the index is not an Integer or is not the index of a fixed variable.
     Essential. See Object documentation whatIsAPrimitive."

    <primitive: 173 error: ec>
    self primitiveFailed'

May be the compile is not logging the method body.
But since the compiler is full uncommented this is super nice to learn and get empowered.

Stef



Reply | Threaded
Open this post in threaded view
|

Re: LearningObject

stepharo
I wanted to avoid to use the class Api becuase with ProtoObject you never know.
I think that I found the problem.
The compilation happens in another thread.


Le 28/1/16 00:17, Clément Bera a écrit :
Hello,

The logging of sources is not part of the compiler. It is part of the behavior API. 

Something like that would work :

ATMinimalLearningObject >> addFromObjectSelector: aSelector
    self class compile: (Object >> aSelector) sourceCode classified: #foo

Now it is strange that the decompiler can't decompile instVarAt: . It looks like it is a bug related to primitive error code decompilation. This is something I should look at during the sprint...


2016-01-27 20:42 GMT+01:00 stepharo <[hidden email]>:
Hi guys

I'm on holidays (no book no mooc no bugs just playing magic good music and hacking a bit)
and I wanted to implemented a fun object that learn from Object by copying the methods.

ProtoObject subclass: #ATMinimalLearningObject
    instanceVariableNames: ''
    classVariableNames: ''
    package: 'MiniActalk2'


ATMinimalLearningObject >> doesNotUnderstand: aMessage

    | sel |
    sel := aMessage selector.
    Transcript show: 'Does not understand ',  sel printString ; cr.
    ^ (Object includesSelector: sel)
        ifTrue: [
                self addFromObjectSelector: sel.
                aMessage sendTo: self ]
        ifFalse: [ super doesNotUnderstand: aMessage ].

ATMinimalLearningObject >> addFromObjectSelector: aSelector

    | method |
    method := OpalCompiler new
                    class: self class;
                    source: (Object sourceCodeAt: aSelector);
                    compile.
    self class addSelector: aSelector withMethod: method.

ATMinimalLearningObject subclass: #ATProtozoid
    instanceVariableNames: 'ff'
    classVariableNames: ''
    package: 'MiniActalk2'


Now it is working but I have the impression that we may have a problem.

When I do
ATProtozoid new instVarAt: 1


I get the following definition for instVarAt:

instVarAt: t1
    self error: 'Decompilation failed'


but

Object sourceCodeAt: #instVarAt: returns the correct string.

 'instVarAt: index
    "Primitive. Answer a fixed variable in an object. The numbering of the variables
     corresponds to the named instance variables, followed by the indexed instance
     variables. Fail if the index is not an Integer or is not the index of a fixed variable.
     Essential. See Object documentation whatIsAPrimitive."

    <primitive: 173 error: ec>
    self primitiveFailed'

May be the compile is not logging the method body.
But since the compiler is full uncommented this is super nice to learn and get empowered.

Stef




Reply | Threaded
Open this post in threaded view
|

Re: LearningObject

Denis Kudriashov
In reply to this post by stepharo
Hi.

Nice trick :)

2016-01-27 20:42 GMT+01:00 stepharo <[hidden email]>:
ATMinimalLearningObject >> addFromObjectSelector: aSelector

    | method |
    method := OpalCompiler new
                    class: self class;
                    source: (Object sourceCodeAt: aSelector);
                    compile.
    self class addSelector: aSelector withMethod: method.

Why compilation is needed? 
Is adding copy of method not working?

  self class addSelector: aSelector withMethod: (Object >> aSelector) copy.

Reply | Threaded
Open this post in threaded view
|

Re: LearningObject

Denis Kudriashov
In reply to this post by stepharo

2016-01-28 8:23 GMT+01:00 stepharo <[hidden email]>:
I wanted to avoid to use the class Api becuase with ProtoObject you never know.
I think that I found the problem.
The compilation happens in another thread.

It is strange. You create new compiler instance for each method. How they can influence each other?
Reply | Threaded
Open this post in threaded view
|

Re: LearningObject

Guillermo Polito
- You should not copy methods *just like that*. Methods are bounded (using the last literal in the literal list) to the class that owns it, to be able to resolve super sends. That is, every time there is a super send, the VM checks to which class it belongs and continues the lookup in the superclass of that class.

-  Maybe it is writing to the sources file that doesn’t work from different processes?

On 28 ene 2016, at 9:53 a.m., Denis Kudriashov <[hidden email]> wrote:


2016-01-28 8:23 GMT+01:00 stepharo <[hidden email]>:
I wanted to avoid to use the class Api becuase with ProtoObject you never know.
I think that I found the problem.
The compilation happens in another thread.

It is strange. You create new compiler instance for each method. How they can influence each other?

Reply | Threaded
Open this post in threaded view
|

Re: LearningObject

Denis Kudriashov

2016-01-28 10:43 GMT+01:00 Guillermo Polito <[hidden email]>:
- You should not copy methods *just like that*. Methods are bounded (using the last literal in the literal list) to the class that owns it, to be able to resolve super sends. That is, every time there is a super send, the VM checks to which class it belongs and continues the lookup in the superclass of that class.

But is not #addSelector:withMethod: should take care about it? I guess traits installation not creates methods by compiling. 
 

-  Maybe it is writing to the sources file that doesn’t work from different processes?

It should be fixed by synchronising such operations. 
Anyway copy approach should not touch source file at all.

Reply | Threaded
Open this post in threaded view
|

Re: LearningObject

stepharo
In reply to this post by Denis Kudriashov
Indeed I could but I thought that recompiling I was sure that everything is correct

Le 28/1/16 09:51, Denis Kudriashov a écrit :
Hi.

Nice trick :)

2016-01-27 20:42 GMT+01:00 stepharo <[hidden email]>:
ATMinimalLearningObject >> addFromObjectSelector: aSelector

    | method |
    method := OpalCompiler new
                    class: self class;
                    source: (Object sourceCodeAt: aSelector);
                    compile.
    self class addSelector: aSelector withMethod: method.

Why compilation is needed? 
Is adding copy of method not working?

  self class addSelector: aSelector withMethod: (Object >> aSelector) copy.


Reply | Threaded
Open this post in threaded view
|

Re: LearningObject

Guillermo Polito
In reply to this post by Denis Kudriashov

On 28 ene 2016, at 11:07 a.m., Denis Kudriashov <[hidden email]> wrote:


2016-01-28 10:43 GMT+01:00 Guillermo Polito <[hidden email]>:
- You should not copy methods *just like that*. Methods are bounded (using the last literal in the literal list) to the class that owns it, to be able to resolve super sends. That is, every time there is a super send, the VM checks to which class it belongs and continues the lookup in the superclass of that class.

But is not #addSelector:withMethod: should take care about it? I guess traits installation not creates methods by compiling. 

For traits. But I wouldn’t be sure for others :).

This is a part of the system that need some love I think...

 

-  Maybe it is writing to the sources file that doesn’t work from different processes?

It should be fixed by synchronising such operations. 
Anyway copy approach should not touch source file at all.


Reply | Threaded
Open this post in threaded view
|

Re: LearningObject

stepharo
In reply to this post by Clément Béra
So I tried with this version and it worked well. So I will keep it.

Le 28/1/16 00:17, Clément Bera a écrit :
self class compile: (Object >> aSelector) sourceCode classified: #foo

Reply | Threaded
Open this post in threaded view
|

Re: LearningObject

stepharo
In reply to this post by Denis Kudriashov


Le 28/1/16 09:53, Denis Kudriashov a écrit :

2016-01-28 8:23 GMT+01:00 stepharo <[hidden email]>:
I wanted to avoid to use the class Api becuase with ProtoObject you never know.
I think that I found the problem.
The compilation happens in another thread.

It is strange. You create new compiler instance for each method. How they can influence each other?

No idea :)
May be this is a problem between the compiler and the source access.