You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@groovy.apache.org by Assia Alexandrova <ko...@gmail.com> on 2017/05/22 04:53:20 UTC

JSR 223 support behavior

Hi all,

My first time here. I wasn't sure weather to post this to dev list, so
please let me know if I should!

I'm trying to hook the latest Groovy interpreter to a JVM scripting
notebook environment (https://github.com/bolerio/seco). At a minimum I need
good JSR 223 support so that symbols/variables can be shared between
scripting languages. With Groovy and its built-in JSR 223 support, it seems
like an assignment:

something = 10

is placed into the common scripting context, but not a definition like this:

def something = 10

Here is a sample program reproducing the issue:

import javax.script.*;
import org.codehaus.groovy.jsr223.*;

public class TestMe
{

  public static void main(String[] args)
  {
    ScriptEngine engine = (ScriptEngine) new
GroovyScriptEngineFactory().getScriptEngine();

    try
    {
      String decl = "def something = 10";
      String stmt = "println something";
      engine.eval(decl);
      engine.eval(stmt);
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }
}

This yields an error: Caused by: groovy.lang.MissingPropertyException: No
such property: something for class: Script2

I played with GroovyShell a bit, passing in my own groovy.lang.Binding
implementation and indeed whenever there is a "def name = value", the
binding setVariable or setProperty are not called.

Is this a bug? If not, is there a way to get access to those symbols
introduced via 'def'. Disclaimer: I'm not a Groovy programmer, just trying
to learn enough to make this work.

Regards

Re: JSR 223 support behavior

Posted by Assia Alexandrova <ko...@gmail.com>.
Hi,

Thanks again for your support! I think more work is needed to sort out
compilation vs. interpretation in a notebook-like environment, which
is what we are building. But using the implementation of that Groovy
console interpreterMode as inspiration, we've made it work with 'defs'
being visible globally.

FYI: http://kobrix.blogspot.com/2017/05/seco-080-release.html

Regards

On Wed, May 24, 2017 at 8:36 AM, Jochen Theodorou <bl...@gmx.org> wrote:
>
>
> On 24.05.2017 09:45, Jochen Theodorou wrote:
> [...]
>>
>> ah, thanks for the clarification... I thought we had changed that
>> already in the past. Seems my memory was not correct here. Extracting
>> the variables of the topmost scope is not the most difficult thing to do
>> I will bring this to the dev list
>
>
>
> looks like my memory was not completely wrong and Guillaume did remember:
>
>>
>> groovy:000> :set interpreterMode true
>>
>> groovy:000> def a = 1
>>
>> ===> 1
>>
>> groovy:000> println a
>>
>> 1
>
>
>
> bye Jochen
>

Re: JSR 223 support behavior

Posted by Jochen Theodorou <bl...@gmx.org>.

On 24.05.2017 09:45, Jochen Theodorou wrote:
[...]
> ah, thanks for the clarification... I thought we had changed that
> already in the past. Seems my memory was not correct here. Extracting
> the variables of the topmost scope is not the most difficult thing to do
> I will bring this to the dev list


looks like my memory was not completely wrong and Guillaume did remember:

>
> groovy:000> :set interpreterMode true
>
> groovy:000> def a = 1
>
> ===> 1
>
> groovy:000> println a
>
> 1


bye Jochen


Re: JSR 223 support behavior

Posted by Jochen Theodorou <bl...@gmx.org>.

On 24.05.2017 05:11, Assia Alexandrova wrote:
[...]
> Ok, so if I understand correctly from this and from some cursory
> reading of the source code around JSR 223, the 'def' keyword operates
> within a lexical scope and that lexical scope must be completely known
> in advance before the statement can be evaluated. There is no "global"
> lexical scope (just like there isn't in Java) that one can operate
> within in a REPL. However, there is a global dynamic scope that is
> accessible by being careful to omit the 'def' keyword (and I suppose
> type names as well?).

sounds about right... no type name either, yes.

> I must admit I don't understand what the
> semantics are, but as long as it makes some sense to Groovy users,
> that's fine.

I hope it does ;)

[...]
>>>
>>> groovy:000> def x = 10;
>>>
>>> ===> 10
>>>
>>> groovy:000> x
>>>
>>> Unknown property: x
>>
>> hmmm... strange... I have the vague memory that somebody already fixed
>> that... ah... right... this is JSR-223 not groovysh. For groovysh we
>> actually do quite some things like transferring import statements and I
>> think also declaration of variables and methods. But JSR-223 was originally
>> intended to always get a complete script, thus we have no such things there.
>> If JSR223 would be in more wider use, we would probably offer a REPL mode
>> for it...
>
> This *is* groovysh, not JSR 223. I just wanted to see how Groovy's own
> REPL behaves and it seems like it behaves the same, specifically it
> seems like every string evaluated has its own lexical scope and that
> lexical scope is lost on the next command. So one shouldn't use 'def'
> inside groovysh either if one want to declare global variables.


ah, thanks for the clarification... I thought we had changed that 
already in the past. Seems my memory was not correct here. Extracting 
the variables of the topmost scope is not the most difficult thing to do 
I will bring this to the dev list

bye Jochen

Re: JSR 223 support behavior

Posted by Assia Alexandrova <ko...@gmail.com>.
Hi,

On Tue, May 23, 2017 at 6:39 AM, Jochen Theodorou <bl...@gmx.org> wrote:
>
>
> On 23.05.2017 03:34, Assia Alexandrova wrote:
>>
>> Hi,
>>
>> Thanks for the prompt response!
>>
>> I am a bit confused. According to what appears to be the official
>> language semantics:
>>
>> http://www.groovy-lang.org/semantics.html#_variable_definition
>>
>> the 'def' keyword is used to declare an untyped variable (i.e. one
>> whose type is Object). So something like
>>
>> def x = 10
>>
>> is then presumably equivalent to two separate statements:
>>
>> def x
>> x = 10
>>
>> What is the difference in semantics between 'def x = 10' and 'x = 10'?
>
>
> "def x" declares a variable x in the current lexical scope.
>
> "x=10" is an assignment to the variable x. In Java the assignment has to be
> done either together with the declaration or after (in a lexical sense) the
> declaration. While Groovy has lexical scopes, Groovy also has some
> constructs with dynamic scopes. Every Closure and every class container can
> define such a dynamic scope. A script is also a class container. The
> important point here is, that in a dynamic scope the declaration may not be
> literal, but programmatically.
>
> So if you do println x, as script, then what are the scopes here? The
> println method call actually is taken and put into a run method, which also
> defines the scope. So the direct scope context for x is the same as the
> method... besides the implicit method, nothing different to Java here yet.
> The parent to the method scope is the class scope. In a script you cannot
> easily define elements here. Unlike Java Groovy does not define this scope
> as lexical, it defines it as dynamic. This means getProperty and setProperty
> methods are used to get or set the value of "x". Thus x is not bound to a
> declaration anymore.
>
> In a script these getProperty and setProperty methods will use the Binding
> to get or set such a value. With the logic of "I can always set the value"
> and "I can get the value only if it has been set before".

Ok, so if I understand correctly from this and from some cursory
reading of the source code around JSR 223, the 'def' keyword operates
within a lexical scope and that lexical scope must be completely known
in advance before the statement can be evaluated. There is no "global"
lexical scope (just like there isn't in Java) that one can operate
within in a REPL. However, there is a global dynamic scope that is
accessible by being careful to omit the 'def' keyword (and I suppose
type names as well?). I must admit I don't understand what the
semantics are, but as long as it makes some sense to Groovy users,
that's fine.

>> Can you point me to how docs where I can learn about transforms and
>> write such a transform?
>
>
> Take a look at
> http://groovy-lang.org/metaprogramming.html#developing-ast-xforms

Great, I will! Looks interesting...

>> I'd like to understand if this behaviors is
>> some side-effect of the implementation of the language or really
>> designed following some rationale. In the latter case, cool, but in
>> the former, I'd take a stab at a writing a transform.
>
>
> well, I hope my explanation above sounds like the cool case ;)
>
>> The following REPL interaction seems too strange to me :-)
>>
>> groovy:000> def x = 10;
>>
>> ===> 10
>>
>> groovy:000> x
>>
>> Unknown property: x
>
>
> hmmm... strange... I have the vague memory that somebody already fixed
> that... ah... right... this is JSR-223 not groovysh. For groovysh we
> actually do quite some things like transferring import statements and I
> think also declaration of variables and methods. But JSR-223 was originally
> intended to always get a complete script, thus we have no such things there.
> If JSR223 would be in more wider use, we would probably offer a REPL mode
> for it...

This *is* groovysh, not JSR 223. I just wanted to see how Groovy's own
REPL behaves and it seems like it behaves the same, specifically it
seems like every string evaluated has its own lexical scope and that
lexical scope is lost on the next command. So one shouldn't use 'def'
inside groovysh either if one want to declare global variables.

Thanks much for your help!

Re: JSR 223 support behavior

Posted by Assia Alexandrova <ko...@gmail.com>.
Hi Paul,

Right....but unfortunately this is within the context of a notebook
tool that others are using to type in and evaluate Groovy code, so I
have no control (unless I do an AST transform as Jochen suggested). I
was surprised by this, but since Groovy's own REPL (groovysh) behaves
the same way, I think regular/experienced Groovy users should be ok
with it.

Regards

On Tue, May 23, 2017 at 7:31 AM, Paul King <pa...@asert.com.au> wrote:
> You can put things into the binding yourself if that helps:
>
> ------------
> import org.codehaus.groovy.jsr223.*
>
> def engine = new GroovyScriptEngineFactory().scriptEngine
> engine.put('something', 10)
> engine.eval('println something')
> ------------
>
> Cheers, Paul.
>
>
> On Tue, May 23, 2017 at 8:39 PM, Jochen Theodorou <bl...@gmx.org> wrote:
>>
>>
>>
>> On 23.05.2017 03:34, Assia Alexandrova wrote:
>>>
>>> Hi,
>>>
>>> Thanks for the prompt response!
>>>
>>> I am a bit confused. According to what appears to be the official
>>> language semantics:
>>>
>>> http://www.groovy-lang.org/semantics.html#_variable_definition
>>>
>>> the 'def' keyword is used to declare an untyped variable (i.e. one
>>> whose type is Object). So something like
>>>
>>> def x = 10
>>>
>>> is then presumably equivalent to two separate statements:
>>>
>>> def x
>>> x = 10
>>>
>>> What is the difference in semantics between 'def x = 10' and 'x = 10'?
>>
>>
>> "def x" declares a variable x in the current lexical scope.
>>
>> "x=10" is an assignment to the variable x. In Java the assignment has to
>> be done either together with the declaration or after (in a lexical sense)
>> the declaration. While Groovy has lexical scopes, Groovy also has some
>> constructs with dynamic scopes. Every Closure and every class container can
>> define such a dynamic scope. A script is also a class container. The
>> important point here is, that in a dynamic scope the declaration may not be
>> literal, but programmatically.
>>
>> So if you do println x, as script, then what are the scopes here? The
>> println method call actually is taken and put into a run method, which also
>> defines the scope. So the direct scope context for x is the same as the
>> method... besides the implicit method, nothing different to Java here yet.
>> The parent to the method scope is the class scope. In a script you cannot
>> easily define elements here. Unlike Java Groovy does not define this scope
>> as lexical, it defines it as dynamic. This means getProperty and setProperty
>> methods are used to get or set the value of "x". Thus x is not bound to a
>> declaration anymore.
>>
>> In a script these getProperty and setProperty methods will use the Binding
>> to get or set such a value. With the logic of "I can always set the value"
>> and "I can get the value only if it has been set before".
>>
>>> Can you point me to how docs where I can learn about transforms and
>>> write such a transform?
>>
>>
>> Take a look at
>> http://groovy-lang.org/metaprogramming.html#developing-ast-xforms
>>
>>> I'd like to understand if this behaviors is
>>> some side-effect of the implementation of the language or really
>>> designed following some rationale. In the latter case, cool, but in
>>> the former, I'd take a stab at a writing a transform.
>>
>>
>> well, I hope my explanation above sounds like the cool case ;)
>>
>>> The following REPL interaction seems too strange to me :-)
>>>
>>> groovy:000> def x = 10;
>>>
>>> ===> 10
>>>
>>> groovy:000> x
>>>
>>> Unknown property: x
>>
>>
>> hmmm... strange... I have the vague memory that somebody already fixed
>> that... ah... right... this is JSR-223 not groovysh. For groovysh we
>> actually do quite some things like transferring import statements and I
>> think also declaration of variables and methods. But JSR-223 was originally
>> intended to always get a complete script, thus we have no such things there.
>> If JSR223 would be in more wider use, we would probably offer a REPL mode
>> for it...
>>
>> bye Jochen
>
>

Re: JSR 223 support behavior

Posted by Paul King <pa...@asert.com.au>.
You can put things into the binding yourself if that helps:

------------
import org.codehaus.groovy.jsr223.*

def engine = new GroovyScriptEngineFactory().scriptEngine
engine.put('something', 10)
engine.eval('println something')
------------

Cheers, Paul.


On Tue, May 23, 2017 at 8:39 PM, Jochen Theodorou <bl...@gmx.org> wrote:

>
>
> On 23.05.2017 03:34, Assia Alexandrova wrote:
>
>> Hi,
>>
>> Thanks for the prompt response!
>>
>> I am a bit confused. According to what appears to be the official
>> language semantics:
>>
>> http://www.groovy-lang.org/semantics.html#_variable_definition
>>
>> the 'def' keyword is used to declare an untyped variable (i.e. one
>> whose type is Object). So something like
>>
>> def x = 10
>>
>> is then presumably equivalent to two separate statements:
>>
>> def x
>> x = 10
>>
>> What is the difference in semantics between 'def x = 10' and 'x = 10'?
>>
>
> "def x" declares a variable x in the current lexical scope.
>
> "x=10" is an assignment to the variable x. In Java the assignment has to
> be done either together with the declaration or after (in a lexical sense)
> the declaration. While Groovy has lexical scopes, Groovy also has some
> constructs with dynamic scopes. Every Closure and every class container can
> define such a dynamic scope. A script is also a class container. The
> important point here is, that in a dynamic scope the declaration may not be
> literal, but programmatically.
>
> So if you do println x, as script, then what are the scopes here? The
> println method call actually is taken and put into a run method, which also
> defines the scope. So the direct scope context for x is the same as the
> method... besides the implicit method, nothing different to Java here yet.
> The parent to the method scope is the class scope. In a script you cannot
> easily define elements here. Unlike Java Groovy does not define this scope
> as lexical, it defines it as dynamic. This means getProperty and
> setProperty methods are used to get or set the value of "x". Thus x is not
> bound to a declaration anymore.
>
> In a script these getProperty and setProperty methods will use the Binding
> to get or set such a value. With the logic of "I can always set the value"
> and "I can get the value only if it has been set before".
>
> Can you point me to how docs where I can learn about transforms and
>> write such a transform?
>>
>
> Take a look at http://groovy-lang.org/metaprogramming.html#developing-ast-
> xforms
>
> I'd like to understand if this behaviors is
>> some side-effect of the implementation of the language or really
>> designed following some rationale. In the latter case, cool, but in
>> the former, I'd take a stab at a writing a transform.
>>
>
> well, I hope my explanation above sounds like the cool case ;)
>
> The following REPL interaction seems too strange to me :-)
>>
>> groovy:000> def x = 10;
>>
>> ===> 10
>>
>> groovy:000> x
>>
>> Unknown property: x
>>
>
> hmmm... strange... I have the vague memory that somebody already fixed
> that... ah... right... this is JSR-223 not groovysh. For groovysh we
> actually do quite some things like transferring import statements and I
> think also declaration of variables and methods. But JSR-223 was originally
> intended to always get a complete script, thus we have no such things
> there. If JSR223 would be in more wider use, we would probably offer a REPL
> mode for it...
>
> bye Jochen
>

Re: JSR 223 support behavior

Posted by Jochen Theodorou <bl...@gmx.org>.

On 23.05.2017 03:34, Assia Alexandrova wrote:
> Hi,
>
> Thanks for the prompt response!
>
> I am a bit confused. According to what appears to be the official
> language semantics:
>
> http://www.groovy-lang.org/semantics.html#_variable_definition
>
> the 'def' keyword is used to declare an untyped variable (i.e. one
> whose type is Object). So something like
>
> def x = 10
>
> is then presumably equivalent to two separate statements:
>
> def x
> x = 10
>
> What is the difference in semantics between 'def x = 10' and 'x = 10'?

"def x" declares a variable x in the current lexical scope.

"x=10" is an assignment to the variable x. In Java the assignment has to 
be done either together with the declaration or after (in a lexical 
sense) the declaration. While Groovy has lexical scopes, Groovy also has 
some constructs with dynamic scopes. Every Closure and every class 
container can define such a dynamic scope. A script is also a class 
container. The important point here is, that in a dynamic scope the 
declaration may not be literal, but programmatically.

So if you do println x, as script, then what are the scopes here? The 
println method call actually is taken and put into a run method, which 
also defines the scope. So the direct scope context for x is the same as 
the method... besides the implicit method, nothing different to Java 
here yet. The parent to the method scope is the class scope. In a script 
you cannot easily define elements here. Unlike Java Groovy does not 
define this scope as lexical, it defines it as dynamic. This means 
getProperty and setProperty methods are used to get or set the value of 
"x". Thus x is not bound to a declaration anymore.

In a script these getProperty and setProperty methods will use the 
Binding to get or set such a value. With the logic of "I can always set 
the value" and "I can get the value only if it has been set before".

> Can you point me to how docs where I can learn about transforms and
> write such a transform?

Take a look at 
http://groovy-lang.org/metaprogramming.html#developing-ast-xforms

> I'd like to understand if this behaviors is
> some side-effect of the implementation of the language or really
> designed following some rationale. In the latter case, cool, but in
> the former, I'd take a stab at a writing a transform.

well, I hope my explanation above sounds like the cool case ;)

> The following REPL interaction seems too strange to me :-)
>
> groovy:000> def x = 10;
>
> ===> 10
>
> groovy:000> x
>
> Unknown property: x

hmmm... strange... I have the vague memory that somebody already fixed 
that... ah... right... this is JSR-223 not groovysh. For groovysh we 
actually do quite some things like transferring import statements and I 
think also declaration of variables and methods. But JSR-223 was 
originally intended to always get a complete script, thus we have no 
such things there. If JSR223 would be in more wider use, we would 
probably offer a REPL mode for it...

bye Jochen

Re: JSR 223 support behavior

Posted by Assia Alexandrova <ko...@gmail.com>.
Hi,

Thanks for the prompt response!

I am a bit confused. According to what appears to be the official
language semantics:

http://www.groovy-lang.org/semantics.html#_variable_definition

the 'def' keyword is used to declare an untyped variable (i.e. one
whose type is Object). So something like

def x = 10

is then presumably equivalent to two separate statements:

def x
x = 10

What is the difference in semantics between 'def x = 10' and 'x = 10'?

Can you point me to how docs where I can learn about transforms and
write such a transform? I'd like to understand if this behaviors is
some side-effect of the implementation of the language or really
designed following some rationale. In the latter case, cool, but in
the former, I'd take a stab at a writing a transform. The following
REPL interaction seems too strange to me :-)

groovy:000> def x = 10;

===> 10

groovy:000> x

Unknown property: x


Regards

On Mon, May 22, 2017 at 1:35 AM, Jochen Theodorou <bl...@gmx.org> wrote:
>
> On 22.05.2017 06:53, Assia Alexandrova wrote:
>>
>> Hi all,
>>
>> My first time here. I wasn't sure weather to post this to dev list, so
>> please let me know if I should!
>>
>> I'm trying to hook the latest Groovy interpreter to a JVM scripting
>> notebook environment (https://github.com/bolerio/seco). At a minimum I
>> need good JSR 223 support so that symbols/variables can be shared
>> between scripting languages. With Groovy and its built-in JSR 223
>> support, it seems like an assignment:
>>
>> something = 10
>>
>> is placed into the common scripting context, but not a definition like this:
>>
>> def something = 10
>
>
> that is by language design
>
>
> [...]
>>
>> Is this a bug? If not, is there a way to get access to those symbols
>> introduced via 'def'. Disclaimer: I'm not a Groovy programmer, just
>> trying to learn enough to make this work.
>
>
> you could write a transform to rewrite the code for those.
>
> But why not simply use it without def?
>
> bye Jochen
>

Re: JSR 223 support behavior

Posted by Jochen Theodorou <bl...@gmx.org>.
On 22.05.2017 06:53, Assia Alexandrova wrote:
> Hi all,
>
> My first time here. I wasn't sure weather to post this to dev list, so
> please let me know if I should!
>
> I'm trying to hook the latest Groovy interpreter to a JVM scripting
> notebook environment (https://github.com/bolerio/seco). At a minimum I
> need good JSR 223 support so that symbols/variables can be shared
> between scripting languages. With Groovy and its built-in JSR 223
> support, it seems like an assignment:
>
> something = 10
>
> is placed into the common scripting context, but not a definition like this:
>
> def something = 10

that is by language design

[...]
> Is this a bug? If not, is there a way to get access to those symbols
> introduced via 'def'. Disclaimer: I'm not a Groovy programmer, just
> trying to learn enough to make this work.

you could write a transform to rewrite the code for those.

But why not simply use it without def?

bye Jochen