Am 15.09.2011, 03:14 Uhr, schrieb bearophile <[email protected]>:

Docs of Tart, a future system language:
http://docs.tart.googlecode.com/hg/intro/index.html

It looks very similar to D, with few idioms turned into nice syntax. It's in early stage of development.

The following are quotations from the docs, I have selected some nice ideas.

---------------------------

http://docs.tart.googlecode.com/hg/intro/types.html

@Flags enum Traits {
  ABSTRACT,
  FINAL,
  STATIC,

  MASK = ABSTRACT | FINAL | STATIC,
}

var x = Traits.ABSTRACT | Traits.FINAL;

The presence of the @Flags annotation causes a number of things to happen:

The default sequence of initialization values is 1, 2, 4, 8, and so on, rather than 0, 1, 2, 3, etc. In other words, any enumeration constant that does not have an explicit initialization expression will be assigned the next available bit number after the previous value. The compiler will auto-generate the bitwise operators | and & for that type. The compiler will also auto-generate the contains() method, which allows the use of the in operator, enabling expressions such as if ABSTRACT in traits. In the current version of Tart, the toString() method is not defined on flag enums.

Note

Tart enumerations do not support Java’s ability to add arbitrary properties to enums.

In Delphi, you don't @Flag the enum itself, but declare a 'set' of the enum type for which all basic set operators are defined. 'does a contain all of b', 'is x in a' and so on. The enum values are converted to bit positions in the set by the compiler. The Tard way looks inspired by that. Anyway it is a nice feature, looks clean, saves typing and documents the use of the enum. You can still add explicit constants if required.

Property Declarations

The def keyword can also be used to define a property. Properties are like variables, except that they are implemented using functions. Whenever you attempt to read from the property, the property’s get function will be invoked, and when you attempt to modify the value, the set function will be called.:

def myProp:int {
  get { return p; }
  set (value) { p = value; }
}

myProp = 1;   // Calls "myProp.set(1)"

This looks like C#. It's one way to do it.

http://docs.tart.googlecode.com/hg/intro/functions.html

Like Python, parameters can be referred to by name as well as position:

print("Hello, World!\n", padding="");

Any parameter can be referred to by its keyword name. The normal mapping of arguments to formal parameters is that positional arguments are assigned first, in order, and then any keyword arguments are assigned to any remaining unfilled parameters.

Sometimes it is useful to specify a parameter that is “keyword only” meaning that it can only be specified via keyword instead of positionally. A semicolon can be used to segregate regular positional parameters from keyword-only parameters:

def print (format:String; npos:int=0, sep=false);

print("Hello world!", npos=1); // OK
print("Hello world!", 1); // ERROR - too many positional arguments

In the above example, only the format argument will be filled in by positional argument - to have additional positional arguments in this case would be an error.

It may help understanding code that uses 'those seldom used 5th parameter' if you had to refer to it by name. Especially in cases where you have lots of "false, 0, null" and you wonder if these would have been the default values and if not, what they do.

http://docs.tart.googlecode.com/hg/intro/classes.html

A protocol represents a contract which a type may conform to. A class or struct is said to support the protocol if that class or struct defines all of the method signatures that are defined by the protocol. Template arguments can be constrained to only match types which support a specified protocol. Classes may declare explicitly that they support a protocol, or the support can be determined implicitly.

A protocol is a kind of abstract type that defines a contract which another type can support. An example would be a “HasToString” protocol:

protocol HasToString {
  def toString -> String;
}

Do I understand that right? They renamed interface to protocol? :)
Well, in C++ at least where a struct can implement interfaces that would be the case. Structs are different creatures in D and the decision was made to use implicit interfaces. There is a bit more to the story I think. Personally I like explicit interfaces and use them where possible.

The extend keyword allows you to add additional methods to a user-defined type:

/* Add an additional method to the String class. */
extend String {
  static def toUpperCase() { /* ... */ }
}

Note however, that you can’t actually change the runtime representation of a type this way. The reason is simple: The extend declaration may not be visible everywhere in the program. If you extend class String, some modules may only see the original, unextended class, while other modules will see the extended version of the class. In order for all of the code to interoperate, the runtime implementation of the class must be the same, regardless of the extension.

This means that the extension can only add certain kinds of things to a type, namely:

    Static methods or properties.
    Final methods or properties.
    Inner types and type aliases.
    Protocol inheritance declarations.

Extensions follow the same scoping rules as other declarations, meaning that they are only in effect if the scope in which they are declared is active.

C++ friend functions, JavaScript and universal calls in D come to my mind. Protocol inheritance should solve itself in D with implicit interfaces. *Did I just say something pro implicit interfaces?* Maybe if I want to add a helper function to someone else's API within my code this feature comes handy. An example might be a curl wrapper that lacks a simple download URL method that supports any protocol.

Sometimes you need to test the type of a variable, the isa keyword can be used for this. It works for both reference types and union types:

if a isa float {
  // ...
}

Many OOP languages only support this for classes, but D also has is(a : b).
I'll make a cut here. You are right, another C++ replacement project is a good source for inspiration.

Reply via email to