[gambit-list] How to handle and access and interact with object members host code
Marc Feeley
feeley at iro.umontreal.ca
Tue Dec 8 17:00:55 EST 2015
In the code I sent, you can use strings, symbols or keywords interchangeably for naming classes and methods. It is just a matter of style.
Your suggestion to add a dot at the end of the variable containing an object is cute. It can be a reminder that a variable contains an object of the host language. Moreover you can avoid the quoting of the method names by using variables, so you could do:
(define Date 'Date)
(define getTime 'getTime)
(define o. (new Date))
(println (o. getTime))
Marc
> On Dec 8, 2015, at 3:07 AM, ben yakawp <ben.lists at yakawp.com> wrote:
>
>> (define o (new 'Date "March 11, 1985"))
>> (println (o getTime:))
>
>
> that looks clear and beautiful, thank you.
>
> Questions
> - is there a reason why you use a quoted symbol for the constructor and
> keywords for the method calls? I like it but I wonder if there are other
> reasons then aesthetic considerations.
>
> - the other thing I was wondering. I think its common that the first
> object in unquoted s-expression is an operator. In the case of "(obj
> method args)" the rules are little confusing because the expression only
> makes sense if you have the contextual knowledge of at least the second
> object (method). Maybe a solution could be to write something like
> (println (o. getTime:))
> With the help of the dot it is immediately clear that the operator is in
> fact an object.
>
>
>
>
>
>
>
> On Mon, Dec 7, 2015, at 10:09 PM, Marc Feeley wrote:
>> Yes the idea is to mimic the OO style. Here’s some tested code:
>>
>> (##declare (extended-bindings) (not safe))
>>
>> (##inline-host-declaration "
>>
>> function getGlobal(name) {
>> return this[name];
>> }
>>
>> ")
>>
>> (define (new constructor . args)
>> (let ((obj (create-object constructor args)))
>> (lambda (method . args)
>> (call-method obj method args))))
>>
>> (define (create-object constructor args)
>> (if (##null? args)
>> (##inline-host-expression
>> "new (getGlobal(@1 at .toString()))()"
>> constructor)
>> (let ((arg1 (##car args))
>> (args (##cdr args)))
>> (if (##null? args)
>> (##inline-host-expression
>> "new (getGlobal(@1 at .toString()))(g_scm2host(@2@))"
>> constructor
>> arg1)
>> (let ((arg2 (##car args))
>> (args (##cdr args)))
>> (if (##null? args)
>> (##inline-host-expression
>> "new
>> (getGlobal(@1 at .toString()))(g_scm2host(@2@),g_scm2host(@3@))"
>> constructor
>> arg1
>> arg2)
>> (let ((arg3 (##car args))
>> (args (##cdr args)))
>> (if (##null? args)
>> (##inline-host-expression
>> "new
>> (getGlobal(@1 at .toString()))(g_scm2host(@2@),g_scm2host(@3@),g_scm2host(@4@))"
>> constructor
>> arg1
>> arg2
>> arg3)
>> (error "too many arguments to
>> constructor")))))))))
>>
>> (define (call-method obj method args)
>> (if (##null? args)
>> (##inline-host-expression
>> "g_host2scm(@1@[@2 at .toString()].call(@1@))"
>> obj
>> method)
>> (let ((arg1 (##car args))
>> (args (##cdr args)))
>> (if (##null? args)
>> (##inline-host-expression
>> "g_host2scm(@1@[@2 at .toString()].call(@1@,g_scm2host(@2@)))"
>> obj
>> method
>> arg1)
>> (let ((arg2 (##car args))
>> (args (##cdr args)))
>> (if (##null? args)
>> (##inline-host-expression
>> "g_host2scm(@1@[@2 at .toString()].call(@1@,g_scm2host(@2@),g_scm2host(@3@)))"
>> obj
>> method
>> arg1
>> arg2)
>> (let ((arg3 (##car args))
>> (args (##cdr args)))
>> (if (##null? args)
>> (##inline-host-expression
>> "g_host2scm(@1@[@2 at .toString()].call(@1@,g_scm2host(@2@),g_scm2host(@3@),g_scm2host(@4@)))"
>> obj
>> method
>> arg1
>> arg2)
>> (error "too many arguments to method")))))))))
>>
>> (define o (new 'Date "March 11, 1985"))
>>
>> (println (o getTime:))
>>
>> (println (o toString:))
>>
>>
>> Marc
>>
>>> On Dec 7, 2015, at 3:17 PM, ben yakawp <ben.lists at yakawp.com> wrote:
>>>
>>> thanks,
>>> so the trick is to mimic the oo style in Gambit.
>>>
>>>
>>> 7 (define (new-Date o)
>>> 8 (let ((obj (##inline-host-expression "new Date()")))
>>> 10 (lambda (f)
>>> 11 (f obj))))
>>> 14
>>> 15 (define date (new-Date "Date"))
>>> 16
>>> 17 (print (date .getTime))
>>>
>>>
>>> What do you think of this notation?
>>>
>>>
>>>
>>> On Mon, Dec 7, 2015, at 06:00 PM, Marc Feeley wrote:
>>>> Here’s a simple example creating a JavaScript Date object and extracting
>>>> the number of milliseconds since January 1, 1970:
>>>>
>>>> (define (new-Date)
>>>> (##inline-host-expression "new Date()"))
>>>>
>>>> (define (.getTime obj)
>>>> (##inline-host-expression "@1 at .getTime()" obj))
>>>>
>>>> (define o (new-Date))
>>>>
>>>> (println (.getTime o))
>>>>
>>>> This is possible because host objects can be used as Scheme objects (they
>>>> are opaque, but you can return them from functions, pass them as function
>>>> parameters and store them in data-structures).
>>>>
>>>> Does that clarify things?
>>>>
>>>> BTW, the above code can be improved quite a bit to make it more general.
>>>> I’m just giving this example to show it is simple to interface to host
>>>> objects.
>>>>
>>>> Marc
>>>>
>>>>
>>>>> On Dec 7, 2015, at 11:44 AM, ben yakawp <ben.lists at yakawp.com> wrote:
>>>>>
>>>>> Just to be a little more precise. Expressing OO style in Scheme was not
>>>>> my primary concern here. The problem I see is that the all of the host
>>>>> languages (except the original C backend) access their library functions
>>>>> through an OO interface. It's not like the library approach in scheme
>>>>> were you can directly use a function after you imported it.
>>>>>
>>>>> That means if you want to use a function from a host language you first
>>>>> have to create an object. But now what is this object in Scheme and what
>>>>> can it do? In the best case, it would check the member calls at compile
>>>>> time. In the worst case it add runtime cost in the backend.
>>>>>
>>>>> But thats just stuff I was thinking about.
>>>>>
>>>>> What I wanted to know in the first place is how I should accessing
>>>>> backing library functions / ffing that are "hidden" behind OO apis.
>>>>> How is this done?
>>>>>
>>>>>
>>>>> On Mon, Dec 7, 2015, at 05:13 PM, Marc Feeley wrote:
>>>>>> At the Scheme level, you can express the OO style in various ways. Here
>>>>>> are 2 that come to mind:
>>>>>>
>>>>>> 1) Your “new” operator could return a closure which receives as a first
>>>>>> parameter the name of the method to be called. So you could:
>>>>>>
>>>>>> (define o (new Lib))
>>>>>> (o print: "hello")
>>>>>>
>>>>>> or
>>>>>>
>>>>>> (define .print '.print)
>>>>>> (o .print "hello")
>>>>>>
>>>>>> 2) You could make .print a function that receives as a first parameter
>>>>>> the object on which the method applies. For example:
>>>>>>
>>>>>> (define .print (lambda (self text) …))
>>>>>> (define o (new Lib))
>>>>>> (.print o "hello")
>>>>>>
>>>>>> You can of course use macros to automate these styles.
>>>>>>
>>>>>> Marc
>>>>>>
>>>>>>> On Dec 7, 2015, at 8:31 AM, ben yakawp <ben.lists at yakawp.com> wrote:
>>>>>>>
>>>>>>> hi
>>>>>>> Sorry if this too obvious, but I don't understand how gambit handles
>>>>>>> objects from the hosts backend.
>>>>>>>
>>>>>>>
>>>>>>> For example: if one would like to construct a 'Node' library for the JS
>>>>>>> backend, how would you do that? The whole node api seems to be object
>>>>>>> oriented. But also the Python standard libaries (batteries) are layed
>>>>>>> out class based. You had to do something like
>>>>>>>
>>>>>>> (define o (new Lib))
>>>>>>> (o.print "hello")
>>>>>>>
>>>>>>> This looks wrong. What am I missing?
>>>>>>>
>>>>>>> Regards
>>>>>>> ben
>>>>>>> _______________________________________________
>>>>>>> Gambit-list mailing list
>>>>>>> Gambit-list at iro.umontreal.ca
>>>>>>> https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
>>>>>>
>>>>
>>> _______________________________________________
>>> Gambit-list mailing list
>>> Gambit-list at iro.umontreal.ca
>>> https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
>>
> _______________________________________________
> Gambit-list mailing list
> Gambit-list at iro.umontreal.ca
> https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
More information about the Gambit-list
mailing list