On Wednesday, 8 January 2014 at 00:23:34 UTC, deed wrote:
From time to time I find the declaration syntax slightly awkward. The main reason is that the identifiers come after the types, making it harder to identify names and get an overview of the code. This bothered me enough to
start playing with alternatives.

My two questions are:

1. Are there technical reasons not to do it this way, like grammar/ambiguity,
   parsing time, etc.?
2. Have others been thinking in same direction playing with converters
   or alternative front ends?

NB! This is by no means any suggestion to change D-syntax.

Modifications:

1. Swap type and name. Like Go, but return type between function name and
   parameter list.
2. Names come first, all other annotations after. ALWAYS. Example:

private const(int)[] foo(const(int)[] all, int newNum, int sum) {}

   becomes

foo const(int)[](all const(int)[], newNum int, sum int) private {}

At this point the readability and overview would be improved IMO.

3. Separate parameter names from their types.

foo(all, newNum, sum) const(int)[](const(int)[], int, int) private {}


A couple of examples from phobos follow below:

//========================================
// From std.container
//========================================
// Current syntax

struct Range
{
    private Node * _first;
    private Node * _last;
    private this(Node* first, Node* last);
    private this(Node* n);
    @property bool empty() const nothrow;
    @property T front();
    void popFront();
    @property Range save();
    @property T back();
    void popBack();
}


// Modified syntax

Range struct
{
    _first Node* private;
    _last Node* private;
    this(first, last) (Node*, Node*) private;
    this(n) (Node*) private;
    empty bool() @property const nothrow;
    front T() @property;
    popFront void();
    save Range() @property ;
    back T() @property;
    popBack void();
}

//========================================
// From std.datetime
//========================================
// Current syntax

abstract class TimeZone
{
public:
    @property string name() const nothrow;
    @property string stdName() const nothrow;
    @property string dstName() const nothrow;
    @property abstract bool hasDST() const nothrow;
    abstract bool dstInEffect(long stdTime) const nothrow;
    abstract long utcToTZ(long stdTime) const nothrow;
    abstract long tzToUTC(long adjTime) const nothrow;
    Duration utcOffsetAt(long stdTime) const nothrow;
    static immutable(TimeZone) getTimeZone(string name);
    static string[] getInstalledTZNames(string subName = "");
private:
this(string name, string stdName, string dstName) immutable pure;
    immutable string _name;
    immutable string _stdName;
    immutable string _dstName;
}


// Modified syntax

TimeZone class abstract
{
public:
    name() string() @property const nothrow;
    stdName() string() @property const nothrow;
    dstName() string() @property const nothrow;
    hasDST() bool() @property const nothrow abstract;
    dstInEffect(stdTime) bool(long) abstract const nothrow;
    utcToTZ(stdTime) long(long) abstract const nothrow;
    tzToUTC(adjTime) long(long) abstract const nothrow;
    utcOffsetAt(stdTime) Duration(long)  const nothrow;
    getTimeZone(name) static immutable TimeZone(string);
    getInstalledTZNames(subName = "") static string[] (string);
private:
this(name, stdName, dstName) (string, string, string) immutable pure;
    _name immutable string;
    _stdName immutable string;
    _dstName immutable string;
}

// Alternative layout:

TimeZone class abstract
{
  public:
    name()                  string()    @property const nothrow;
    stdName()               string()    @property const nothrow;
    dstName()               string()    @property const nothrow;
hasDST() bool() @property const nothrow abstract;
    dstInEffect( stdTime )  bool(long)  abstract const nothrow;
    utcToTZ( stdTime )      long(long)  abstract const nothrow;
    tzToUTC( adjTime )      long(long)  abstract const nothrow;
    utcOffsetAt( stdTime )  Duration(long)  const nothrow;
    getTimeZone( name )     static immutable TimeZone(string);
    getInstalledTZNames( subName = "")
                            static string[](string);
  private:
this(name, stdName, dstName) (string, string, string) immutable pure;
    _name    immutable string;
    _stdName immutable string;
    _dstName immutable string;
}

//========================================
// From std.getopt
//========================================
// Current syntax

private void getoptImpl(T...)(ref string[] args, ref configuration cfg, T opts);

void handleOption(R)(string option, R receiver, ref string[] args,
        ref configuration cfg, bool incremental);

private bool optMatch(string arg, string optPattern, ref string value,
    configuration cfg);


// Modified syntax

getoptImpl(args, cfg, opts) private
    (T...) void (ref string[], ref configuration, T);

handleOption(option, receiver, args, cfg, incremental)
    (R) void (string, R, ref string[], ref configuration, bool);

optMatch(arg, optPattern, value, cfg) private
    bool (string, string, ref string, configuration);

It's really a matter of opinion which is best, which in my opinion is trumped by the familiarity of C-style syntax. I'm sure I could work with either way.

Reply via email to