On Wednesday, 30 April 2014 at 01:38:46 UTC, Narrator wrote:
The unbelievable amount of time and energy that's been spent discussing the smallest syntax, you would think that D would, at the very least, have better looking function signatures, but it doesn't.

auto zip(Ranges...)(Ranges ranges) if (Ranges.length && allSatisfy!(isInputRange, Ranges)); auto zip(Ranges...)(StoppingPolicy sp, Ranges ranges) if (Ranges.length && allSatisfy!(isInputRange, Ranges));

fn zip<B, U: Iterator<B>>(self, other: U) -> Zip<Self, U>

IIUC:

1. The Rust function is non-variadic
2. The Rust function has no StoppingPolicy equivalent
3. The Rust function is a method of some type, such as Zip or Chain, which must be declared explicitly in every such type.

Here is the equivalent D syntax:

auto zip(R)(R other) if (isInputRange!R)

It is shorter than the Rust version.

auto chain(Ranges...)(Ranges rs) if (Ranges.length > 0 && allSatisfy!(isInputRange, staticMap!(Unqual, Ranges)) && !is(CommonType!(staticMap!(ElementType, staticMap!(Unqual, Ranges))) == void));

fn chain<U: Iterator<A>>(self, other: U) -> Chain<Self, U>

Same as points 1 and 3 above. Most of that boilerplate comes from validating the variadic parameter types.

template map(fun...) if (fun.length >= 1)
auto map(Range)(Range r) if (isInputRange!(Unqual!Range));

fn map<'r, B>(self, f: |A|: 'r -> B) -> Map<'r, A, B, Self>

Same as points 1 and 3 above (D's version allows specifying multiple functions).

Not sure what 'r or |A| means in Rust syntax, but I guess this would be the equivalent D syntax:

auto map(R)(R delegate(T))

Note that D's real version has the function alias as a template parameter, and not as a runtime parameter, meaning that you will have a guarantee of a separate template instantiation for every different map predicate. This allows you to make assumptions about the performance of the generated code which don't rely as much on expected compiler optimizations (although I don't know what guarantees Rust makes about this).

template filter(alias pred) if (is(typeof(unaryFun!pred)))
auto filter(Range)(Range rs) if (isInputRange!(Unqual!Range));

fn filter<'r>(self, predicate: |&A|: 'r -> bool) -> Filter<'r, A, Self>

As above, though D's filter also accepts only one predicate.

MaxType!(T1, T2, T) max(T1, T2, T...)(T1 a, T2 b, T xs) if (is(typeof(a < b)));

pub fn max<T: TotalOrd>(v1: T, v2: T) -> T

Same as point 1 above. Also, the Rust version requires that the two values have exactly the same type.

Reply via email to