[gambit-list] How to handle and access and interact with object members host code

Marc Feeley feeley at iro.umontreal.ca
Mon Dec 7 16:09:16 EST 2015


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



More information about the Gambit-list mailing list