| FazBrowse Wikipedia Viewer | Main Page | | |
| Viewing: https://en.wikipedia.org/wiki/D_programming_language |
| Contents |
|---|
| Features |
| Programming paradigms |
| Imperative |
| Parallelism |
| Metaprogramming |
| Memory management |
| SafeD |
| Scope lifetime safety |
| Lifetime safety of assignments |
| Further reading |
| D | |||||
|---|---|---|---|---|---|
| Paradigm | Multi-paradigm: functional, imperative, object-oriented | ||||
| Designed by | Walter Bright, Andrei Alexandrescu (since 2007) | ||||
| Developer | D Language Foundation | ||||
| First appeared | 8 December 2001;24 years ago (2001-12-08) | ||||
FeatureseditD is not source-compatible with C and C++ source code in general. However, any code that is legal in both C/C++ and D should behave in the same way. Like C++, D has closures, anonymous functions, compile-time function execution, design by contract, ranges, built-in container iteration concepts, and type inference. D's declaration, statement and expression syntaxes also closely match those of C++. Unlike C++, D also implements garbage collection, first-class arrays (std::array in C++ are technically not first-class), array slicing, nested functions and lazy evaluation. D uses Java-style single inheritance with interfaces and mixins rather than C++-style multiple inheritance. D is a systems programming language. Like C++, and unlike application languages such as Java and C#, D supports low-level programming, including inline assembler. Inline assembler allows programmers to enter machine-specific assembly code within standard D code. System programmers use this method to access the low-level features of the processor that are needed to run programs that interface directly with the underlying hardware, such as operating systems and device drivers. Low-level programming is also used to write higher performance code than would be produced by a compiler. D supports function overloading and operator overloading. Symbols (functions, variables, classes) can be declared in any order; forward declarations are not needed. In D, text character strings are arrays of characters, and arrays in D are bounds-checked. D has first-class types for complex and imaginary numbers. Programming paradigmseditD supports five main programming paradigms: ImperativeeditImperative programming in D is almost identical to that in C. Functions, data, statements, declarations and expressions work just as they do in C, and the C runtime library may be accessed directly. However, unlike C, D's foreach loop construct allows looping over a collection. D also allows nested functions, which are functions that are declared inside another function, and which may access the enclosing function's local variables. importstd.stdio,std.algorithm,std.range;
voidmain(){
int[]a1=[0,1,2,3,4,5,6,7,8,9];
int[]a2=[6,7,8,9];
// must be immutable to allow access from inside a pure function
immutablepivot=5;
intmySum(inta,intb)purenothrow/* pure function */{
// ref to enclosing-scope
if(b<=pivot){
returna+b;
}else{
returna;
}
}
// passing a delegate (closure)
autoresult=reduce!mySum(chain(a1,a2));
writeln("Result: ",result);// Result: 15
// passing a delegate literal
result=reduce!((a,b)=>(b<=pivot)?a+b:a)(chain(a1,a2));
writeln("Result: ",result);// Result: 15
}
Alternatively, the above function compositions can be expressed using Uniform function call syntax (UFCS) for more natural left-to-right reading: (b <= pivot) ? a + b : a)();\nwriteln(\"Result: \", result);\n"}}'>autoresult=a1.chain(a2).reduce!mySum();
writeln("Result: ",result);
result=a1.chain(a2).reduce!((a,b)=>(b<=pivot)?a+b:a)();
writeln("Result: ",result);
ParallelismeditParallel programming concepts are implemented in the library, and do not require extra support from the compiler. However the D type system and compiler ensure that data sharing can be detected and managed transparently. importstd.stdio,std.concurrency,std.variant;
voidfoo(){
boolcont=true;
while(cont){
// Delegates are used to match the message type.
receive(
(intmsg)=>writeln("int received: ",msg),
(Tidsender){cont=false;sender.send(-1);},
(Variantv)=>writeln("huh?")// Variant matches any type
);
}
}
voidmain(){
autotid=spawn(&foo);// spawn a new thread running foo()
foreach(i;0..10){
tid.send(i);// send some integers
}
tid.send(1.0f);// send a float
tid.send("hello");// send a string
tid.send(thisTid);// send a struct (Tid)
receive((intx)=>writeln("Main thread received message: ",x));
}
MetaprogrammingeditMetaprogramming is supported through templates, compile-time function execution, tuples, and string mixins. The following examples demonstrate some of D's compile-time features. Templates in D can be written in a more imperative style compared to the C++ functional style for templates. This is a regular function that calculates the factorial of a number: enumfactorial7=Factorial!(7);
This is an example of compile-time function execution (CTFE). Ordinary functions may be used in constant, compile-time expressions provided they meet certain criteria: // hypothetical module which contains a function that parses Foo source code
// and returns equivalent D code
importFooToD;
voidmain(){
mixin(fooToD(import("example.foo")));
}
Memory managementeditMemory is usually managed with garbage collection, but specific objects may be finalized immediately when they go out of scope. This is what the majority of programs and libraries written in D use. Explicit memory management is possible using the overloaded operator new, by calling C's malloc and free directly, or implementing custom allocator schemes such as stack allocation with fallback, RAII-style allocation, reference counting, or shared reference counting. Garbage collection can be controlled: programmers may add and exclude memory ranges from being observed by the collector, can disable and enable the collector and force either a generational or full collection cycle. The language documentation provides examples of how to implement alternative memory management schemes for scenarios where garbage collection is not preferred. In functions, struct instances are by default allocated on the stack, while class instances by default allocated on the heap (with only reference to the class instance being on the stack). However this can be changed for classes, for example using standard library template std.typecons.scoped, or by using new for structs and assigning to a pointer instead of a value-based variable. In functions, static arrays (of known size) are allocated on the stack. For dynamic arrays, one can use the core.stdc.stdlib.alloca function (similar to alloca in C), to allocate memory on the stack. The returned pointer can be used (recast) into a (typed) dynamic array, by means of a slice (however resizing array, including appending must be avoided; and for obvious reasons they must not be returned from the function). A scope keyword can be used both to annotate parts of code, but also variables and classes/structs, to indicate they should be destroyed (destructor called) immediately on scope exit. Whatever the memory is deallocated also depends on implementation and class-vs-struct differences. std.experimental.allocator contains modular and composable allocator templates to create custom allocators for specific use cases. SafeDeditSafeD is the name given to the subset of D that can be guaranteed to be memory safe. Functions marked @safe are checked at compile time to ensure that they do not use any features that could result in corruption of memory, such as pointer arithmetic and unchecked casts. Any other functions called must also be marked as @safe or @trusted. Functions can be marked @trusted for the cases where the compiler cannot distinguish between safe use of a feature that is disabled in SafeD and a potential case of memory corruption. Scope lifetime safetyeditInitially under the banners of DIP1000 and DIP25 (now part of the language specification), D provides protections against certain ill-formed constructions involving the lifetimes of data. The current mechanisms in place primarily deal with function parameters and stack memory; however, the language design roadmap includes plans to expand lifetime tracking within the D programming language, drawing on concepts from the Rust programming language. (influenced by ideas from Rust programming language). Lifetime safety of assignmentseditWithin @safe code, the lifetime of an assignment involving a reference type is checked to ensure that the lifetime of the assignee is longer than that of the assigned. For example: importstd;
classBase{
public:
virtualvoidprint3i(inta,intb,intc)=0;
};
classDerived:publicBase{
private:
intfield;
public:
explicitDerived(intfield):
field(field){}
voidprint3i(inta,intb,intc){
std::println("a = {}",a);
std::println("b = {}",b);
std::println("c = {}",c);
}
intmul(intfactor){
returnfield*factor;
}
};
Derived*createInstance(inti){
returnnewDerived(i);
}
voiddeleteInstance(Derived*&d){
deleted;
d=0;
}
On D: "dmd front end now switched to Boost license". Retrieved 9 September 2014.Further readingedit
| |||||
| Features | |||||
| Standard library |
| ||||
| Compilers | |||||
| IDEs | |||||
| Comparison with other languages | |||||
| Descendant languages | |||||
| Designer | |||||
| |||||