The D language

Started by
90 comments, last by Nitage 17 years, 10 months ago
Quote:Original post by azherdev
I just want my C# code to compile to native code... is that so much to ask? Darn framework.


Why? I am outside my league here but as computers advance, JIT compilation will continue to become superior to native compilation. Already it outperforms native in certain cases.
Advertisement
Quote:Original post by Lode
[...]-with easier support for making vectors pointers to a mix of parent and child classes with virtual functions, like pointer containers that automatically destroy objects, note that pointer containers aren't in the standard at the moment[...]
boost::shared_ptr?
Quote:[...]-with a programmer NEVER needing to use "new" and "delete", with all situations that could require the use of those having a replacement that auto-deletes (for example the vectors and pointer containers)[...]
So you're saying we should get rid of dynamic memory management and instead require programmers to use built-in types that perform similar but more limited roles?
Quote:[...]-with a MUCH simpeler form to use iterators to elements of containers, I'm sorry but I dislike a variable type with a name like std::vector<int>::iterator, there has to be a better way to handle this, if needed make containers and iterators part of the language itself, for example the type int+ could be an iterator to containers of ints[...]
Is 'int+' a random access iterator, a bidirectional iterator (if not, which direction?), an inserter iterator (front or back?), and how do I overload the type 'int+' so I can make it behave differently?
Quote:[...]-with fixed point types[...]
This is more a processor design issue IMO, and I still wonder why new processor designs don't include instructions for such a thing. Sure, it can be emulated with software, but its much slower than with dedicated hardware (much like emulating 128-bit floating point on an integer-only machine). I love my AMD hardware, but I really wish they had introduced fixed-point instructions with their AMD64 architecture.

Quote:Original post by MaulingMonkey
Quote:Original post by The C modest god
Actually I think headers are really good.


They violate the principle of DRY, or Don't Repeat Yourself. Better to have documentation autogenerated from the implementation source with the function signatures and synopsis than to be forced to manually write header files.
The alternative seems to be to make all function definitions inline with the class definition, which adds extra indenting and prevents decent organization. Well, that or you're just moving the header to the top of the source file and either losing static typing (with some kind of 'object' class that you have to cast around all the time as a kind of pseudodynamic typing) or preventing circular references between types.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Quote:Original post by h3r3tic
Lenghty but interesting post ensues ...


Great post! I'm not expecting that trying out D will be 100% pure unobstructed joy, and the somewhat lacking (as others have said) standard library is a bit worrying but I do think that the language has a lot of potential and if it catches on, the library will surely grow and improve. I really hope D takes off, because I think C++ would benefit from that, too, as the two languages would probably influence each other a lot with both sides borrowing successful concepts from the other.



Quote:Original post by daerid
Consider a class that as one of it's members has a HANDLE to an open file.

When the object dies, you don't necessarily care about how much memory it's taking up, but you definitely want that HANDLE to the open file to have CloseHandle() called on it, or you get an orphaned open file (one of the most annoying things about windows EVER).

That sounds like more of a API issue than a language issue.

Beginner in Game Development?  Read here. And read here.

 

Quote:Original post by Drakex
Alright then. This is a trivial example, but demonstrates a few key issues: operator overloading, templates, classes, and overall syntax:


Not to step on your toes, but those asserts in your D code could be rewritten using D's Design By Contract syntax:


import std.stdio;class MyContainer(T){        // snip	T opIndex(uint index)        in        {                assert(index >= 0 && index < mData.length);        }        body	{				return mData[index];	}		T opIndexAssign(T value, uint index)        in        {                assert(index >= 0 && index < mData.length);        }        body	{		return mData[index] = value;	}       // snip	}


In addition to in blocks, you can also use out blocks to verify return data. When DBC is inabled, inblocks are called before entering the function body, out blocks are called after exiting the function body and before returning to the call site. This can all be turned on and off with a command line switch.

But in this case, the bounds checks are superfluous. Arrays are automatically bounds checked at runtime unless -release is specified during compilation. When it's enabled and an out of bounds index is detected, an exception is thrown.

Here's another neat example:

// C++bool doSomething(){   // blah blah   return false;   // blah blah   return true;}void someFunction(){   bool success = DoSomething();      if(!success)   {      // code to execute on failure   }   else   {       // code to execute on success   }   // code to execute always}


void DoSomething(){   // blah blah   throw new Exception("yadda yadda");   // blah blah}void SomeFunction(){   scope(exit)   {      // code to always execute when the function exits normally or otherwise   }   scope(failure)   {      // code to execute only during exception stack unwinding   }   scope(success)   {      // code to execute only when the function exits normally   }   DoSomething();}


It's not a big thing, but it looks cleaner than if/else blocks or gotos and labels. It's just one of the many little things that gives D a nice feel.
isn't that like a try, catch, finally block?

well the code i've seen so far is well... syntactic sugar. especially that first code example. i didn't see any reason why i would move from C++ to D, based on that. well let me correct that. not "move" but start to program in D.

Beginner in Game Development?  Read here. And read here.

 

The 'syntactic sugar' argument is flawed - any Turing complete language has exactly the same power, so you could resaonably argue that anything apart from directly coded machine language is 'syntactic sugar'.

From what I've seen, D is far cleaer than C++.

Consider this C++:

template <size_t X, size_t Y>class Matrix{//c'tors, d'tor & matrix maths operators};


How would you add a member function that sets the matrix to the identity matrix? In C++, you'd have to duplicate the entire class definition, using partial specialization to pick out square matrices (the only kind of matrices that have identity matrices).

In D, you could use static if to do that. Not only is such a method much simpler to use, it's also much more obvious what the intent of the programmer is and there's far less duplication.

I'm seriously considering D for my next project, the only stalling blocks are ( big ones unfortunatley):

  • My code base is written in C++

  • Most external libraries I'm interested in are also in C++

/*
As for the scope guards, they're not like totally try catch finally (and find me 'finally' in C++ ... ). You can read more here: http://www.digitalmars.com/d/exception-safe.html
*/

D does not have any big killer, but rather dozens of small improvements that, when combined, make programming much easier.


1. Slicing

char[] foo = "foo bar";char[] bar = foo[4 .. $];// bar == "bar"



2. Associative arrays

int[char[]] myMap;myMap["foo"] = 1;myMap["bar"] = 2;myMap["baz"] = 3;writefln(myMap["bar"]);// prints '2'


3. Delegates

class Foo {	this (int a) {		this.a = a;	}	void foo() {		writefln(a);	}	int a;}void main() {	auto dg = &(new Foo(5)).foo;	dg();		// prints '5'}


4. Automatic type inference (Like in the previous example)

auto x = 2 + 3.4f;writefln(typeid(typeof(x)));// prints 'float'


5. static if

template fact(int a) {	static if (0 == a) {		const int fact = 1;	} else {		const int fact = a * fact!(a - 1);	}}void main() {	writefln(fact!(4));		// prints '24'}


6. Nested functions

void main() {	void foo() {		writefln("Yo !");	}	foo();}


7. Function and delegate literals

void foo(int delegate() x) {	writefln(x());}void main() {	int someInt = 123;	foo( { return someInt; } );}


8. Typesafe varargs

void main() {	void foo(int[] arr ...) {		writefln(arr);	}	foo(1, 2);		// prints '[1,2]'	foo(3);			// prints '[3]'}


9. Array bounds checking (can be disabled)

int[] arr = new int[3];arr[10] = 4;		// runtime exception with line number


10. String switches

switch ("foo") {	case "bar": writefln(1); break;	case "foo": writefln(2); break;		// that's the case :P}


11. Painless static initialization

class Foo {	int a = 5;	int b = 3;	typedef int Bar = 10;	Bar c;		// initialized to 10}



etc etc etc ...


Yes, many of these can be accomplished in C++ thru the use of [insert your favourite hack name here] or Boost, but I wouldn't call them clean solutions
Most of it is syntactic sugar of some sort, but then any language would be syntactic sugar for asm.
Quote:Original post by Drakex
Quote:Does anyone have some code that shows D doing something better than C++ or at least being done in a less complicated fashion?


Alright then. This is a trivial example, but demonstrates a few key issues: operator overloading, templates, classes, and overall syntax:

*** Source Snippet Removed ***

The equivalent in D:

*** Source Snippet Removed ***

Just........ yeah. THAT'S why I don't like C++ anymore.


I'm sorry but that is a pathetic example and poor C++ code.

Quote:Original post by Drakex
// Hell let's make an iterator, I don't have a clue how to do that in C++.


Well that says it all...
Quote:Original post by Nitage
How would you add a member function that sets the matrix to the identity matrix? In C++, you'd have to duplicate the entire class definition, using partial specialization to pick out square matrices (the only kind of matrices that have identity matrices).




Well not quite, it's not true it's just the most obvious solution but it's not the only one. I can think of two methods that don't require (partial) specialization.

1.

#include <cstddef>#include <boost/utility/enable_if.hpp>#include <boost/mpl/equal_to.hpp>#include <boost/mpl/size_t.hpp>namespace mpl = boost::mpl;template < std::size_t M, std::size_t N >matrix<M, N>& identity(matrix<M, N>& m,                       typename boost::enable_if<                           mpl::equal_to<                               mpl::size_t<M>,                               mpl::size_t<N>                            >                        >::type* = 0) { /*<-insert-code->*/}


2.

//.... just imagine headers herenamespace mpl = boost::mpl;using namespace boost::mpl::placeholders;template < typename Matrix >struct sqr_matrix {    Matrix& identity() {          Matrix& this_ = static_cast<Matrix&>(*this);          //.......          return this_;    }    // add all other ops that are only for square matrix};template < std::size_t M, std::size_t N >struct matrix    : mpl::if_<          mpl::equal_to<              mpl::size_t<M>,              mpl::size_t<N>          >,          sqr_matrix< matrix<M, N> >,          mpl::empty_base       >::type{ .... };

This topic is closed to new replies.

Advertisement