scoping rules

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

scoping rules

Sonny To
sorry for the newb question but i find this behavior odd

(let ((handler (android.os.Handler (android.os.Looper:getMainLooper)))
      (c context))
  (handler:post (lambda ()
                        (let ((t (android.widget.Toast:makeText (as
android.app.Application c) "foobar"  1000)))
                          (t:show))
                        )))

To get this example to work I had to bind c context in the top level let
in the second let, I have to use c instead of context directly.
(android.widget.Toast:makeText (as android.app.Application context)
will complain

/dev/stdin:45:93: unbound location: context

it could not see the context binding.
Should it not look in the environment? context is definitely in the
environment because the c binding works
Reply | Threaded
Open this post in threaded view
|

Re: scoping rules

Per Bothner
On 09/17/2017 09:51 AM, Sonny To wrote:

> sorry for the newb question but i find this behavior odd
>
> (let ((handler (android.os.Handler (android.os.Looper:getMainLooper)))
>        (c context))
>    (handler:post (lambda ()
>                          (let ((t (android.widget.Toast:makeText (as
> android.app.Application c) "foobar"  1000)))
>                            (t:show))
>                          )))
>
> To get this example to work I had to bind c context in the top level let
> in the second let, I have to use c instead of context directly.
> (android.widget.Toast:makeText (as android.app.Application context)
> will complain
>
> /dev/stdin:45:93: unbound location: context
>
> it could not see the context binding.
> Should it not look in the environment? context is definitely in the
> environment because the c binding works

That does sound like a bug.  Probably the interaction of dynamic (environment) name-lookup
combined with the use of the anonymous class.

If you can create a simple non-Android test-case I'll take a look.

It is recommended to include the line:

     (define-variable context)

as that tells the compiler to look for 'context' in the dynamic environment,
and avoids warnings when using --warn-undefined-variable.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: scoping rules

Sonny To
ok let me see if i can reproduce this outside of android

On Sun, Sep 17, 2017 at 10:45 AM, Per Bothner <[hidden email]> wrote:

> On 09/17/2017 09:51 AM, Sonny To wrote:
>>
>> sorry for the newb question but i find this behavior odd
>>
>> (let ((handler (android.os.Handler (android.os.Looper:getMainLooper)))
>>        (c context))
>>    (handler:post (lambda ()
>>                          (let ((t (android.widget.Toast:makeText (as
>> android.app.Application c) "foobar"  1000)))
>>                            (t:show))
>>                          )))
>>
>> To get this example to work I had to bind c context in the top level let
>> in the second let, I have to use c instead of context directly.
>> (android.widget.Toast:makeText (as android.app.Application context)
>> will complain
>>
>> /dev/stdin:45:93: unbound location: context
>>
>> it could not see the context binding.
>> Should it not look in the environment? context is definitely in the
>> environment because the c binding works
>
>
> That does sound like a bug.  Probably the interaction of dynamic
> (environment) name-lookup
> combined with the use of the anonymous class.
>
> If you can create a simple non-Android test-case I'll take a look.
>
> It is recommended to include the line:
>
>     (define-variable context)
>
> as that tells the compiler to look for 'context' in the dynamic environment,
> and avoids warnings when using --warn-undefined-variable.
> --
>         --Per Bothner
> [hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: scoping rules

Sonny To
I was able to reproduce strange behavior with symbol scope on the jvm:

(define (run-in-ui-thread fn)
  (let ((t :: java.lang.Thread (java.lang.Thread (object (java.lang.Runnable)
                                                         ((run)::void
                                                          (fn))))))
    (t:start)))

(run-in-ui-thread (lambda ()
                    (let ( (a 1)
                           (b 2)
                           (c (+ a b)))
                      (display c))))

here's the stacktrace

/dev/stdin:37:15: warning - no declaration seen for b
#|kawa:39|# Exception in thread "Thread-4" /dev/stdin:37:13: unbound location: a
        at gnu.mapping.DynamicLocation.get(DynamicLocation.java:36)
        at atInteractiveLevel$Mn5.lambda1(stdin:37)
        at atInteractiveLevel$Mn5.lambda1$check(stdin:34)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
        at gnu.mapping.Procedure.applyToConsumerDefault(Procedure.java:75)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
        at gnu.kawa.functions.ApplyToArgs.applyToConsumerA2A(ApplyToArgs.java:132)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
        at gnu.mapping.CallContext.runUntilDone(CallContext.java:586)
        at gnu.mapping.CallContext.runUntilValue(CallContext.java:669)
        at gnu.mapping.Procedure.apply1(Procedure.java:148)
        at atInteractiveLevel$Mn1$0.run(stdin:5)
        at java.lang.Thread.run(Thread.java:745)


This however works:

(run-in-ui-thread (lambda ()
                    (let ( (a 1)
                           (b 2))
                      (display (+ a b)))))



On Sun, Sep 17, 2017 at 9:49 PM, Sonny To <[hidden email]> wrote:

> ok let me see if i can reproduce this outside of android
>
> On Sun, Sep 17, 2017 at 10:45 AM, Per Bothner <[hidden email]> wrote:
>> On 09/17/2017 09:51 AM, Sonny To wrote:
>>>
>>> sorry for the newb question but i find this behavior odd
>>>
>>> (let ((handler (android.os.Handler (android.os.Looper:getMainLooper)))
>>>        (c context))
>>>    (handler:post (lambda ()
>>>                          (let ((t (android.widget.Toast:makeText (as
>>> android.app.Application c) "foobar"  1000)))
>>>                            (t:show))
>>>                          )))
>>>
>>> To get this example to work I had to bind c context in the top level let
>>> in the second let, I have to use c instead of context directly.
>>> (android.widget.Toast:makeText (as android.app.Application context)
>>> will complain
>>>
>>> /dev/stdin:45:93: unbound location: context
>>>
>>> it could not see the context binding.
>>> Should it not look in the environment? context is definitely in the
>>> environment because the c binding works
>>
>>
>> That does sound like a bug.  Probably the interaction of dynamic
>> (environment) name-lookup
>> combined with the use of the anonymous class.
>>
>> If you can create a simple non-Android test-case I'll take a look.
>>
>> It is recommended to include the line:
>>
>>     (define-variable context)
>>
>> as that tells the compiler to look for 'context' in the dynamic environment,
>> and avoids warnings when using --warn-undefined-variable.
>> --
>>         --Per Bothner
>> [hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: scoping rules

Sonny To
forgot to mention this is from the master branch and the jar was built
using ant -Denable-android=true

On Mon, Sep 18, 2017 at 11:29 AM, Sonny To <[hidden email]> wrote:

> I was able to reproduce strange behavior with symbol scope on the jvm:
>
> (define (run-in-ui-thread fn)
>   (let ((t :: java.lang.Thread (java.lang.Thread (object (java.lang.Runnable)
>                                                          ((run)::void
>                                                           (fn))))))
>     (t:start)))
>
> (run-in-ui-thread (lambda ()
>                     (let ( (a 1)
>                            (b 2)
>                            (c (+ a b)))
>                       (display c))))
>
> here's the stacktrace
>
> /dev/stdin:37:15: warning - no declaration seen for b
> #|kawa:39|# Exception in thread "Thread-4" /dev/stdin:37:13: unbound location: a
>         at gnu.mapping.DynamicLocation.get(DynamicLocation.java:36)
>         at atInteractiveLevel$Mn5.lambda1(stdin:37)
>         at atInteractiveLevel$Mn5.lambda1$check(stdin:34)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>         at java.lang.reflect.Method.invoke(Method.java:497)
>         at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
>         at gnu.mapping.Procedure.applyToConsumerDefault(Procedure.java:75)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>         at java.lang.reflect.Method.invoke(Method.java:497)
>         at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
>         at gnu.kawa.functions.ApplyToArgs.applyToConsumerA2A(ApplyToArgs.java:132)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>         at java.lang.reflect.Method.invoke(Method.java:497)
>         at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
>         at gnu.mapping.CallContext.runUntilDone(CallContext.java:586)
>         at gnu.mapping.CallContext.runUntilValue(CallContext.java:669)
>         at gnu.mapping.Procedure.apply1(Procedure.java:148)
>         at atInteractiveLevel$Mn1$0.run(stdin:5)
>         at java.lang.Thread.run(Thread.java:745)
>
>
> This however works:
>
> (run-in-ui-thread (lambda ()
>                     (let ( (a 1)
>                            (b 2))
>                       (display (+ a b)))))
>
>
>
> On Sun, Sep 17, 2017 at 9:49 PM, Sonny To <[hidden email]> wrote:
>> ok let me see if i can reproduce this outside of android
>>
>> On Sun, Sep 17, 2017 at 10:45 AM, Per Bothner <[hidden email]> wrote:
>>> On 09/17/2017 09:51 AM, Sonny To wrote:
>>>>
>>>> sorry for the newb question but i find this behavior odd
>>>>
>>>> (let ((handler (android.os.Handler (android.os.Looper:getMainLooper)))
>>>>        (c context))
>>>>    (handler:post (lambda ()
>>>>                          (let ((t (android.widget.Toast:makeText (as
>>>> android.app.Application c) "foobar"  1000)))
>>>>                            (t:show))
>>>>                          )))
>>>>
>>>> To get this example to work I had to bind c context in the top level let
>>>> in the second let, I have to use c instead of context directly.
>>>> (android.widget.Toast:makeText (as android.app.Application context)
>>>> will complain
>>>>
>>>> /dev/stdin:45:93: unbound location: context
>>>>
>>>> it could not see the context binding.
>>>> Should it not look in the environment? context is definitely in the
>>>> environment because the c binding works
>>>
>>>
>>> That does sound like a bug.  Probably the interaction of dynamic
>>> (environment) name-lookup
>>> combined with the use of the anonymous class.
>>>
>>> If you can create a simple non-Android test-case I'll take a look.
>>>
>>> It is recommended to include the line:
>>>
>>>     (define-variable context)
>>>
>>> as that tells the compiler to look for 'context' in the dynamic environment,
>>> and avoids warnings when using --warn-undefined-variable.
>>> --
>>>         --Per Bothner
>>> [hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: scoping rules

Sonny To
In reply to this post by Sonny To
sorry the problem with this example is due to my ignorance on scheme's
let. I'm use to clojure's let
let* is what I should have used

On Mon, Sep 18, 2017 at 11:29 AM, Sonny To <[hidden email]> wrote:

> I was able to reproduce strange behavior with symbol scope on the jvm:
>
> (define (run-in-ui-thread fn)
>   (let ((t :: java.lang.Thread (java.lang.Thread (object (java.lang.Runnable)
>                                                          ((run)::void
>                                                           (fn))))))
>     (t:start)))
>
> (run-in-ui-thread (lambda ()
>                     (let ( (a 1)
>                            (b 2)
>                            (c (+ a b)))
>                       (display c))))
>
> here's the stacktrace
>
> /dev/stdin:37:15: warning - no declaration seen for b
> #|kawa:39|# Exception in thread "Thread-4" /dev/stdin:37:13: unbound location: a
>         at gnu.mapping.DynamicLocation.get(DynamicLocation.java:36)
>         at atInteractiveLevel$Mn5.lambda1(stdin:37)
>         at atInteractiveLevel$Mn5.lambda1$check(stdin:34)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>         at java.lang.reflect.Method.invoke(Method.java:497)
>         at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
>         at gnu.mapping.Procedure.applyToConsumerDefault(Procedure.java:75)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>         at java.lang.reflect.Method.invoke(Method.java:497)
>         at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
>         at gnu.kawa.functions.ApplyToArgs.applyToConsumerA2A(ApplyToArgs.java:132)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>         at java.lang.reflect.Method.invoke(Method.java:497)
>         at gnu.mapping.CallContext$ReflectMethodHandle.invokeExact(CallContext.java:726)
>         at gnu.mapping.CallContext.runUntilDone(CallContext.java:586)
>         at gnu.mapping.CallContext.runUntilValue(CallContext.java:669)
>         at gnu.mapping.Procedure.apply1(Procedure.java:148)
>         at atInteractiveLevel$Mn1$0.run(stdin:5)
>         at java.lang.Thread.run(Thread.java:745)
>
>
> This however works:
>
> (run-in-ui-thread (lambda ()
>                     (let ( (a 1)
>                            (b 2))
>                       (display (+ a b)))))
>
>
>
> On Sun, Sep 17, 2017 at 9:49 PM, Sonny To <[hidden email]> wrote:
>> ok let me see if i can reproduce this outside of android
>>
>> On Sun, Sep 17, 2017 at 10:45 AM, Per Bothner <[hidden email]> wrote:
>>> On 09/17/2017 09:51 AM, Sonny To wrote:
>>>>
>>>> sorry for the newb question but i find this behavior odd
>>>>
>>>> (let ((handler (android.os.Handler (android.os.Looper:getMainLooper)))
>>>>        (c context))
>>>>    (handler:post (lambda ()
>>>>                          (let ((t (android.widget.Toast:makeText (as
>>>> android.app.Application c) "foobar"  1000)))
>>>>                            (t:show))
>>>>                          )))
>>>>
>>>> To get this example to work I had to bind c context in the top level let
>>>> in the second let, I have to use c instead of context directly.
>>>> (android.widget.Toast:makeText (as android.app.Application context)
>>>> will complain
>>>>
>>>> /dev/stdin:45:93: unbound location: context
>>>>
>>>> it could not see the context binding.
>>>> Should it not look in the environment? context is definitely in the
>>>> environment because the c binding works
>>>
>>>
>>> That does sound like a bug.  Probably the interaction of dynamic
>>> (environment) name-lookup
>>> combined with the use of the anonymous class.
>>>
>>> If you can create a simple non-Android test-case I'll take a look.
>>>
>>> It is recommended to include the line:
>>>
>>>     (define-variable context)
>>>
>>> as that tells the compiler to look for 'context' in the dynamic environment,
>>> and avoids warnings when using --warn-undefined-variable.
>>> --
>>>         --Per Bothner
>>> [hidden email]   http://per.bothner.com/