A mechanism for specifying static type signatures (NOT STATIC TYPING)

Discussion in 'Ruby' started by Charles Oliver Nutter, Sep 30, 2007.

  1. JRuby's main compiler is complete, so I'm starting to kick around ideas
    for a second compiler.

    The goal of the second compiler would be to produce normal-looking Java
    classes that are actually just Ruby code underneath. Constructing them
    in the normal Java way would invoke initialize; calling methods in the
    normal Java way would dynamically call the associated method.

    I talk about it in the second half of this post:

    http://headius.blogspot.com/2007/09/compiler-is-complete.html

    Now before anyone cries foul, this is not about adding static typing to
    Ruby; it's about finding a way to specify what types should be inserted
    into the generated Java class to make things easy on the Java side,
    while avoiding incompatible changes to JRuby.

    Since so many of you have a better perception of beauty in DSL-like
    syntaxes than I do, I figured you might have a good suggestion.

    The first version I proposed on the blog would be a simple map in the
    class body of the form

    {<return type> => [<arg type 1>, <arg type 2> ...]}

    as in

    {String => [Integer, Array]}
    def mymethod(i, a) ...

    which would appear to Java code as

    public String mymethod(Integer i, List a) { ...

    or perhaps

    public String mymethod(int i, List a) { ...

    But I know it's not particularly pretty. So here's the requirements:

    - provide a way to specify the types of an immediately-following method
    definition; this is only going to be a compiler hint, so it doesn't have
    to (and perhaps should avoid) having any side-effects.
    - have no lasting side-effects when run nomally. The above code would
    just produce a hash that gets immediately thrown away if run in e.g.
    Matz's Ruby.
    - not require any syntactic or library changes to Ruby, so the same code
    can run unmodified on any implementation.

    Ideas?

    - Charlie
     
    Charles Oliver Nutter, Sep 30, 2007
    #1
    1. Advertising

  2. Charles Oliver Nutter

    Konrad Meyer Guest

    --nextPart2443716.LtE7EfqCJa
    Content-Type: text/plain;
    charset="iso-8859-1"
    Content-Transfer-Encoding: quoted-printable
    Content-Disposition: inline

    Quoth Charles Oliver Nutter:
    > JRuby's main compiler is complete, so I'm starting to kick around ideas=20
    > for a second compiler.
    >=20
    > The goal of the second compiler would be to produce normal-looking Java=20
    > classes that are actually just Ruby code underneath. Constructing them=20
    > in the normal Java way would invoke initialize; calling methods in the=20
    > normal Java way would dynamically call the associated method.
    >=20
    > I talk about it in the second half of this post:
    >=20
    > http://headius.blogspot.com/2007/09/compiler-is-complete.html
    >=20
    > Now before anyone cries foul, this is not about adding static typing to=20
    > Ruby; it's about finding a way to specify what types should be inserted=20
    > into the generated Java class to make things easy on the Java side,=20
    > while avoiding incompatible changes to JRuby.
    >=20
    > Since so many of you have a better perception of beauty in DSL-like=20
    > syntaxes than I do, I figured you might have a good suggestion.
    >=20
    > The first version I proposed on the blog would be a simple map in the=20
    > class body of the form
    >=20
    > {<return type> =3D> [<arg type 1>, <arg type 2> ...]}
    >=20
    > as in
    >=20
    > {String =3D> [Integer, Array]}
    > def mymethod(i, a) ...
    >=20
    > which would appear to Java code as
    >=20
    > public String mymethod(Integer i, List a) { ...
    >=20
    > or perhaps
    >=20
    > public String mymethod(int i, List a) { ...
    >=20
    > But I know it's not particularly pretty. So here's the requirements:
    >=20
    > - provide a way to specify the types of an immediately-following method=20
    > definition; this is only going to be a compiler hint, so it doesn't have=

    =20
    > to (and perhaps should avoid) having any side-effects.
    > - have no lasting side-effects when run nomally. The above code would=20
    > just produce a hash that gets immediately thrown away if run in e.g.=20
    > Matz's Ruby.
    > - not require any syntactic or library changes to Ruby, so the same code=

    =20
    > can run unmodified on any implementation.
    >=20
    > Ideas?
    >=20
    > - Charlie


    I rather like Okke's suggestion to use method name / argument name hints.
    ex:
    Ruby:
    def str_my_method(int_blah, ary_bar)
    end

    Java:
    String my_method(int blah, List bar){
    }

    or so.

    But if you're sticking with a Hash preceding the method, I think a better=20
    order would be {[Integer, Array] =3D> String} (as mentioned by someone's=20
    comment on your blog).

    Thanks a bunch,
    =2D-=20
    Konrad Meyer <> http://konrad.sobertillnoon.com/

    --nextPart2443716.LtE7EfqCJa
    Content-Type: application/pgp-signature; name=signature.asc
    Content-Description: This is a digitally signed message part.

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.7 (GNU/Linux)

    iD8DBQBG/2Y/CHB0oCiR2cwRAolqAKCAxrelzqIWd1a3JHTgdJOa79aSZwCguyiB
    uHn6luVQl/r4d9ISJ3NpMK4=
    =EFRO
    -----END PGP SIGNATURE-----

    --nextPart2443716.LtE7EfqCJa--
     
    Konrad Meyer, Sep 30, 2007
    #2
    1. Advertising

  3. Charles Oliver Nutter

    ara.t.howard Guest

    On Sep 30, 2007, at 2:30 AM, Charles Oliver Nutter wrote:

    > JRuby's main compiler is complete, so I'm starting to kick around
    > ideas for a second compiler.
    >
    > The goal of the second compiler would be to produce normal-looking
    > Java classes that are actually just Ruby code underneath.
    > Constructing them in the normal Java way would invoke initialize;
    > calling methods in the normal Java way would dynamically call the
    > associated method.
    >
    > I talk about it in the second half of this post:
    >
    > http://headius.blogspot.com/2007/09/compiler-is-complete.html
    >
    > Now before anyone cries foul, this is not about adding static
    > typing to Ruby; it's about finding a way to specify what types
    > should be inserted into the generated Java class to make things
    > easy on the Java side, while avoiding incompatible changes to JRuby.
    >
    > Since so many of you have a better perception of beauty in DSL-like
    > syntaxes than I do, I figured you might have a good suggestion.
    >
    > The first version I proposed on the blog would be a simple map in
    > the class body of the form
    >
    > {<return type> => [<arg type 1>, <arg type 2> ...]}
    >
    > as in
    >
    > {String => [Integer, Array]}
    > def mymethod(i, a) ...
    >
    > which would appear to Java code as
    >
    > public String mymethod(Integer i, List a) { ...
    >
    > or perhaps
    >
    > public String mymethod(int i, List a) { ...
    >
    > But I know it's not particularly pretty. So here's the requirements:
    >
    > - provide a way to specify the types of an immediately-following
    > method definition; this is only going to be a compiler hint, so it
    > doesn't have to (and perhaps should avoid) having any side-effects.
    > - have no lasting side-effects when run nomally. The above code
    > would just produce a hash that gets immediately thrown away if run
    > in e.g. Matz's Ruby.
    > - not require any syntactic or library changes to Ruby, so the same
    > code can run unmodified on any implementation.
    >
    > Ideas?
    >


    my thoughts are that this will lead to other enhancements - compiler
    hints - so why not invent some sort of unifying syntax up front as
    other compilers have. for instance

    pragma :mymethod do |m|
    m[String, Array] => String
    m[Integer, Array] => Integer
    end

    so this is specifying two signatures for a polymorphic method. of
    course you'd have a shortcut

    signature :mymethod, [String, Array] => Integer

    extending the building method class for this is very appealing

    Method:)mymethod).pragma do
    map [String, Array] => String,
    [Integer, Array] => Integer
    end

    where to block above is defined thusly

    class Method
    def pragma &block
    (( @pragma ||= Pragma.new self )).configure &block
    end

    class Pragma
    def initialize method
    @method = method
    @signatures = []
    @dsl = DSL.new self
    end

    class DSL
    def initialize pragma
    @pragma = pragma
    end

    def configure &block
    instance_eval &block
    end

    def map sig = {}
    sig.each do |argv, returned|
    @pragma.signatures << [argv, returned]
    end
    end
    end
    end
    end


    i like the idea of sticking it into Method and pulling the DSL out in
    it's own namespace for the instance_eval lets you have a really
    powerful syntax. for instance this can work:

    Method:)mymethod).pragma do
    map variardic => void
    end

    simply by

    class Module
    class Pragma
    class DSL
    ( VARIARDIC = Object.new ).freeze
    ( VOID = Object.new ).freeze
    def variardic() VARIARDIC end
    def void() VOID end
    end
    end
    end

    it's unrelated, but you might one or two idea from this:

    http://codeforpeople.com/lib/ruby/parseargs/parseargs-0.3.0/README

    it's bit rotted a bit, but at one time i put a bit of thought into
    what the various types of ruby arglists could be and how to manage
    that compactly.

    keep up the good work on jruby.

    cheers.

    a @ http://drawohara.com/
    --
    we can deny everything, except that we have the possibility of being
    better. simply reflect on that.
    h.h. the 14th dalai lama
     
    ara.t.howard, Sep 30, 2007
    #3
  4. Charles Oliver Nutter

    Tom Guest

    > Now before anyone cries foul, this is not about adding static typing to
    > Ruby


    If it provides hints for the compiler to cry on obvious errors, I
    don't care what people call it.

    > {<return type> => [<arg type 1>, <arg type 2> ...]}


    I find it rather confusing that the return value is in front of the
    argument list. Why not:

    > args Integer, Array, String
    > def mymethod(i, a) ...


    The last one is the return value. I think Haskell uses a somewhat
    similar notation: f :: a -> b -> c

    This could be implemented as a class method that does nothing in
    normal
    ruby. This could be called a library change though.

    Otherwise:
    > [Integer, Array, String]
    > def mymethod(i, a) ...
     
    Tom, Sep 30, 2007
    #4
  5. On 9/30/07, Charles Oliver Nutter <> wrote:
    > JRuby's main compiler is complete, so I'm starting to kick around ideas
    > for a second compiler.
    >
    > The goal of the second compiler would be to produce normal-looking Java
    > classes that are actually just Ruby code underneath. Constructing them
    > in the normal Java way would invoke initialize; calling methods in the
    > normal Java way would dynamically call the associated method.
    >
    > I talk about it in the second half of this post:
    >
    > http://headius.blogspot.com/2007/09/compiler-is-complete.html
    >
    > Now before anyone cries foul, this is not about adding static typing to
    > Ruby; it's about finding a way to specify what types should be inserted
    > into the generated Java class to make things easy on the Java side,
    > while avoiding incompatible changes to JRuby.
    >
    > Since so many of you have a better perception of beauty in DSL-like
    > syntaxes than I do, I figured you might have a good suggestion.
    >
    > The first version I proposed on the blog would be a simple map in the
    > class body of the form
    >
    > {<return type> => [<arg type 1>, <arg type 2> ...]}
    >
    > as in
    >
    > {String => [Integer, Array]}
    > def mymethod(i, a) ...
    >
    > which would appear to Java code as
    >
    > public String mymethod(Integer i, List a) { ...
    >
    > or perhaps
    >
    > public String mymethod(int i, List a) { ...
    >
    > But I know it's not particularly pretty. So here's the requirements:
    >
    > - provide a way to specify the types of an immediately-following method
    > definition; this is only going to be a compiler hint, so it doesn't have
    > to (and perhaps should avoid) having any side-effects.
    > - have no lasting side-effects when run nomally. The above code would
    > just produce a hash that gets immediately thrown away if run in e.g.
    > Matz's Ruby.
    > - not require any syntactic or library changes to Ruby, so the same code
    > can run unmodified on any implementation.
    >
    > Ideas?


    The only thing that I can think of which is guaranteed to meet all
    three requirements is some kind of pragma syntax which is a comment to
    other implementations:

    # @@javatype String(Integer, List)

    Anything which relies on executable Ruby code to express pragmas risks
    running afoul of SOME DSL or another.

    --
    Rick DeNatale

    My blog on Ruby
    http://talklikeaduck.denhaven2.com/
     
    Rick DeNatale, Oct 2, 2007
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Spur
    Replies:
    0
    Views:
    358
  2. Michele Simionato
    Replies:
    4
    Views:
    457
    darkbeethoven
    Jun 5, 2012
  3. JimLad
    Replies:
    0
    Views:
    526
    JimLad
    Jan 26, 2010
  4. Replies:
    0
    Views:
    252
  5. Tim Bates
    Replies:
    40
    Views:
    613
    James Britt
    May 25, 2004
Loading...

Share This Page