#1511 User Defined Pass-By-Value Types, Structs

poltomb Wed 27 Apr 2011

I have just recently stumbled upon this site, and it so far looks like the answer to my prayers. The one drawback in all the languages that I really like is the lack of user defined pass-by-value types. I am a Java developer through and through, it's what I know and love. Java does not have this feature, but another language that I like does have it: C# (structs). I understand the "everything is an object" idea, and I support it completely, the one thing that keeps me from using new languages is either the lack of this feature or the lack of similarity to my known languages.

This language, to me, looks like Mr. Java married Ms. C# and had one gorgeous looking daughter which was lovingly named Fantom (Fan for short :D ). One of the features that is drawing me to this language is TRUE properties, ones with storage.

The only feature this language is missing is the idea of user defined pass-by-value types.

Since I have found nothing regarding structs/user defined value types both in the documentation and in the discussions here, this is my official proposal for C, C++, and C# like structs, but with a few more restrictions.

Proposal:

Unified pass-by-value type heirarchy and user defined pass-by-value types

Class Heriarchy

  • abstract Struct
    • Bool
    • Int
    • Float
    • Str (if Str objects are immutable)
    • ... (user defined structs)

Semantics

  • Descendents of Struct will be final.
  • Struct may not be extended explicitly (like Facet).
  • Descendents of Struct may only contain fields that are descendents of Struct.
  • Bool, Int, Float (and Str) literals will reman the same, and all their functionality will remain the same as well.

Syntax

struct MyStruct
{
  // fields may be other value types
  Bool b
  Int i
  Float f
  Str s
  
  // ctors are the same as other objects
  
  // methods are the same as other objects
}
struct MyOtherStruct
{
  // since MyStruct is a struct, it can be included in other structs
  MyStruct mine
}

I invite anyone to please help improve this specification and give comments/suggestions.

brian Thu 28 Apr 2011

Hi poltomb,

Welcome to Fantom and I am glad you like what you see so far.

The main problem with true pass-by-value structure types is that their main purpose in life is performance optimization to avoid heap allocations. But the JVM doesn't support them (behind the basic scalars bool, int, etc). So adding struct types to Fantom wouldn't really have any performance boost when running on the JVM.

There have been rumblings about potential value types being added to the JVM, but given the glacial pace of Java advancement I wouldn't hold my breath. That said, JVMs like HotSpot are amazing in their ability to optimize things. For example HotSpot can perform escape analysis to determine that an object isn't used outside of a given method and then allocate it on the stack vs the heap.

So right now the only real value I see is potential optimization for .NET if it becomes a highly used runtime. In which case what I was thinking was maybe adding a @Struct facet that could by be used by the CLR. We have also talked about something like a "struct type" being used for automatic equals, hash, constructor support.

poltomb Thu 28 Apr 2011

Thanks for the info! I understand that the idea behind them was optimization, but I'm thinking about ease of use when doing this. Whether it does a heap operation in the background or not is not really a concern of mine. For now, I was thinking that structs could be a syntactical and semantic shortcut for something like this (in Java)

final class MyValueType
{
  // with getters and setters (omitted here to be concise)
  private boolean b;
  private int i;
  private double d;
  private String s;

  public MyValueType(boolean b, int i, double d, String s)
  {
    this.b = b;
    this.i = i;
    this.d = d;
    this.s = s;
  }

  public MyValueType copy()
  {
    return new MyValueType(b,i,d,s);
  }
}

Whenever a struct was assigned to ANY variable, the object would be copied, rather than just the reference being copied. I stress the "any" because with AspectJ and reflection, I can emulate this for everything except local variables. Since there are no pointcuts for local variables in AspectJ (or any other AOP library that I found) you cannot force this kind of functionality consistently throughout a system. So my argument boils down to: it is easier for the programmer to implement, and force, a type to always be passed by value.

I hope this info helps explain my reason for suggestion.

go4 Thu 28 Apr 2011

removed

brian Thu 28 Apr 2011

I think what you will find when you start coding in Fantom, that most of these types you would consider a "struct type" are designed as const immutable types in Fantom. So it actually works exactly opposite - you never want to copy them because everyone can safely share a reference to the same instance. This is how Date, Time, DateTime, Point, Size, Rect, Font, etc all work.

go4 Sat 30 Apr 2011

removed

jodastephen Wed 4 May 2011

This is partly a request for automatic equals, hashCode and constructors to enable quick and easy bean creation. This still seems like a no-brainer enhancement/missing feature to me.

DanielFath Wed 4 May 2011

I thought they did consider it, but the problem was reflection was 10 times slower than writing equals / hashCode by hand.

go4 Mon 31 Jul 2017

Yes, it's safe to optimize the const immutable type as pass-by-value struct type.

Login or Signup to reply.