const x: i32 = 92;
D has less syntax: const int x = 92;
Just for fun, read each declaration out loud. const x: i32 = 92;
D has less syntax: const int x = 92;
Just for fun, read each declaration out loud.I like the syntaxes of each, although Ada is too verbose to me, and with Factor and Common Lisp I have a skill issue.
fn ArrayListType(comptime T: type) type {
D: T ArrayListType(T)() {This reminds me of C in the 1970s where the compiler assumed every typo was a new variable of type int. Explicit is good.
It's the default, because most templates are templated on types. If you want a constant int as part of the template type,
ArrayListType(int I)
> This reminds me of C in the 1970s where the compiler assumed every typo was a new variable of type intI think you're referring to function declarations without prototypes. D's syntax does not suffer from that issue.
BTW,
T func(T)(T x) { return x + 1; }
is a declaration of a "function template". The first parameter list consists of the template parameters, and are compile time types and constants. The second parameter list is the conventional function parameter list. If the first parameter list is omitted, then it's a function. struct ArrayListType(T) {
?But I agree it probably returns a struct type.
Assuming that's the case, you're right and the equivalent would be:
Zig:
fn ArrayListType(comptime T: type) type {
D: ArrayList!T ArrayListType(T)() {
But now the D version is more specific about what it returns, so it's still not exactly equivalent.If you must return different types depending on the argument in D, it's also possible.
Here's a silly example:
struct ArrayList(T, alias capacity) {
private T[capacity] array;
private uint _length;
uint length() const => _length;
T get(uint index) const => array[index];
void add(T t) {
array[_length++] = t;
}
}
struct EmptyList(T) {
uint length() const => 0;
}
/// This will return a different type depending on the length argument,
/// which is like a Zig comptime argument.
/// We cannot return the type itself, but the result is very similar.
auto createArrayList(T, alias length)() {
static if (length == 0) {
return EmptyList!T();
} else {
return ArrayList!(T, length)();
}
}
void main()
{
import std.stdio;
auto empty = createArrayList!(int, 0);
writeln(empty);
auto list = createArrayList!(int, 2);
list.add(5);
list.add(6);
writeln(list);
}
Result: EmptyList!int()
ArrayList!(int, 2)([5, 6], 2)Regardless, we are now very far removed from the original code I was commenting on, which doesn't use auto to return different types.
const std = @import("std");
D: import std; import std=std; const my_module = @import("my_module.zig");
This allows you to access pub (public) declarations from my_module.zig through the my_module identifier.Zig:
const std = @import("std");
pub fn main() !void {
// std is like a namespace here
std.debug.print("Hello, World!\n", .{});
}
D: import std.stdio;
void main()
{
// no namespace here, "writeln" and everything else in "std.stdio" is imported
writeln("Hello, World!");
}
The closest to Zig in D would be: import io = std.stdio;
void main()
{
io.writeln("Hello, World!");
} std.stdio.writeln("Hello, world!");