Menu

Experiment: structs

2013-07-15
2013-07-17
  • Julien Ponge

    Julien Ponge - 2013-07-15

    Over the last few days I experimented with the definition of structs, like struct in good old C or record in Pascal. They are basically great to store data. How many times did we write boilerplate data classes in Java? :-)

    You can checkout my branch at https://github.com/jponge/golo-lang/tree/wip/structs

    Documentation is given at https://github.com/jponge/golo-lang/blob/wip/structs/doc/structs.asciidoc and a sample can be checked at https://github.com/jponge/golo-lang/blob/wip/structs/samples/structs.golo

    Note that structs are not classes yet. They are really designed for storing data. By default, instances of a struct are mutable, but a "frozen copy" can be obtained.

    In either case we provide strict semantics on equals() and hashCode() definitions.

    Finally struct instances also have a nice toString() method.

    So... what's the point of having structures when there are dynamic objects? Well, if all you need is storing data and you know in advance what members you need then choosing struct is a no-brainer. Indeed, it compiles to JVM classes, and as such, they are way faster than dynamic objects.

    One thing structs don't do and that dynamic objects do is invoking "fake" methods if you pass a closure as a member value. But given that closures are method handles, you can still do something around the lines of:

    struct Foo = { bar }
    
    # (...)
    let foo = Foo(|x| -> x + 1)
    foo: bar(): invoke(1)
    

    Looking forward to your feedback!

     
  • Philippe Charriere

    hi

    if i write that struct Human = {firstName, lastName, atchoum}, then i have to initialize like that :

    let h = Human(firstName,lastName,something) #or h=Human()
    

    it would be fine, if i could write (like optional parameters of a function):

    let h = Human(firstName,lastName) #something is null (default)
    

    ... unless it is expensive

     
    • Julien Ponge

      Julien Ponge - 2013-07-16

      Basically it means generating lots of constructors. I believe that if you want to initialize just a subset of members then the following form is probably better:

      let h = Human(): firstName("foo"): lastName("bar")
      
       
      • Philippe Charriere

        yes, you're right

         
  • Philippe Charriere

    hi again,

    i've played with it and it's great

    Augmentations run VERY well

    struct human = {firstName, lastName, atchoum}
    
    augment kindofclasses.types.human {
        function hello = |this| {
            println("hello " + this:firstName() + " "+ this:lastName())
        }
    }
    
    function Human = |firstName, lastName| {
        let h = human(firstName,lastName,null)
        h:atchoum(->println(h:firstName()+" : atchoum !"))
        return h
    }
    
    let sam = Human("Sam", "lePirate")
    sam:hello()
    sam:atchoum():invokeWithArguments()
    
     

    Last edit: Philippe Charriere 2013-07-16
  • Julien Ponge

    Julien Ponge - 2013-07-16

    Glad you like it :-)

    Note that you should be able to use invoke() instead of invokeWithArguments().

     
    • Philippe Charriere

      i think i've a little problem with invoke

       
  • Julien Ponge

    Julien Ponge - 2013-07-17

    I just added a few goodies...

    A number of helper methods are now being generated:

    • members() returns a tuple of the member names,
    • values() returns a tuple with the current member values,
    • iterator() provides an iterator over a structure where each element is a tuple [member, value],
    • get(name) returns the value of a member by its name,
    • set(name, value) updates the value of a member by its name, and returns the same structure.

    Structs now inherit from the abstract gololang.GoloStruct Java class.

    Do you like it?

     

Log in to post a comment.