To begin in D coming from Python

bearophile bearophileHUGS at lycos.com
Mon Jul 21 06:07:16 PDT 2008


Luis P. Mendes:

Welcome to the D language. I think there are other people around here that come from the Python language.
For more questions like these I suggest you the D.learn newsgroup.

> I use to program in Python, but I need some programs to run much faster.  
> So, D seems to be as the best programming language for my needs.

Most of the times D is faster than CPython, but:
- Developing in Python is faster or much faster.
- In Python you have more already written libs, and they often are written in C, so you have speed anyway. In D you will probably more often write things by yourself.
- D is younger and less used, so you will find 20 times more bugs in the D implementations than in CPython.
- In Python there is NumPy, Cython, Psyco, ShedSkin, Inline, Weave and many ways to link external C/Fortran code, so you often don't miss speed.
- D too can be used by Python, with Pyd.
- Sometimes D code is slower, for example if you use associative arrays (python dicts), and in other situations, so you have to benchmark your code.
- If you write a D program the way you write Python, you will often see programs almost as fast as Python ones, or just a bit faster (or sometimes slower). So if you want to go faster you generally must write in a lower-level style. You may need months to understand what this means.
- D programs can be quite faster than CPython ones, but if you need speed you may have to use C instead of D, because the D compilers aren't much refined as GCC. I find all the time programs that run 2-3 times faster in C with GCC than in D with DMD (and their source code is exactly the same). When I need more speed I drop to C.
- CPython is written in C, so C is much better integrated with Python than D.
- If you want to give your code to other people, everyone has a C compiler, while not everyone has a D compiler and knows how to fix bugs in your D code.


> Still, there's a long way to go because I've never programmed in C.

D language is almost multi-level: you can program it almost as Python, almost as C (low level), or more generally in a middle way.
If you need speed you have to program in a low-level style, and at this level D looks more like C, so essentially you will have to learn C. The good thing is that D will allow you to learn it progressively, with a softer learning curve.


> To begin with, is version 2 just a developer version or should I start by 
> using it?

If you are on Windows I warmly suggest you to learn the D 1.x version, like the DMD compiler V.1.033.

Note that the D world is currently in a mess, because the standard library (Phobos) isn't much standard anymore, lot of people (not me yet) are now using an external almost-de-facto standard lib named Tango, that you may want to use in the future (or even right now). I presume lot of people are just waiting for the developers of D to just give up in developing Phobos and switch to Tango as official built-in std lib.


> In Python, lists can have variables, functions, text and others as 
> elements.  As far as I can recall from reading a C book, arrays in C 
> don't have this possibility.  What about it in D?

Python lists (that are arrays dynamic on the right) use dynamic typing. In D arrays are statically typed, so you can put only one type inside. There are arrays of variants/boxes that allow you to create arrays with mixed types, but I think they are rarely used in D.

CPython isn't slow because it's badly written. Its C sources are probably quite more optimized than the C sources of DMD, and some parts of Cpython come from people like Tim Peters and R. Hettinger and more, that have invented first-class algorithms absent in the D implementation (for example to search strings into other strings, to sort items, to hash items, etc). CPython is slower because it's dynamically typed and because most name access require a hashing, etc.
That in summary means that if you want to write faster programs (in D) you have to give up something: like the dynamic typing.


> And regarding list comprehensions like li = [elem*2 for elem in li]?  is 
> there something close in D?

List comprehensions are food for Python programmers, but they are not present in D, recently I have written a whole post about this:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=73868

So you can:
- write a normal loop
- use the map/filter of DMD 2.x
- use the things you can find in some libraries, like this large one of mine:
http://www.fantascienza.net/leonardo/so/libs_d.zip
(You may need the "bud" tool to use this in a simple way, because the D language is dumb still being unable to find modules by itself).
Or the Tools lib from Downs.

Notes:
- But you are a newbie of D, so it may be better for you to exercise yourself in the "basic" D language first, before using external libs (and finding if they are good for you).
- If you want to write fast programs you probably can't use high/python-like level of coding in the speed-critical parts of your program (but you can use it in all the other parts to shorten your code, and hopefully to put in less bugs).

So the Python code:
li = [elem*2 for elem in li]

In normal D becomes:
foreach (ref elem; li)
	elem *= 2;

But that's in-place. To be closer to the Python version you need something like:

typeof(li) li2;
li2.length = li.length;
foreach (i, elem; li)
	li2[i] = elem * 2;
li = li2;
(if "li" isn't an array, but something that behaves like an array, then that code may not work, so you may have to keep the "i" counter manually, but this is a very uncommon situation).


Or shorter, but possibly slower (I assume li is really a dynamic array and not something else):
li = li.dup;
foreach (ref elem; li)
	elem *= 2;


With my libs it may become:
li = map((BaseType1!(li) elem){ return elem*2; }, li);

If you know that the type of "li" is T it becomes:
li = map((T elem){ return elem*2; }, li);

With the map() of the std.algorithm of the D 2.x the syntax is probably shorter.
With Downs' Tools it will have a different syntax. 


> For example, how could I do something like:
> valores = []
> for c in lista_campos: valores.append(getattr(self,c)), so that I can 
> have all the 

Python is slow because it's a dynamic language, while D is a static one, so you will have to give up most of the reflection capabilities of Python (expecially if you need running speed and you don't want to write tons of code), like the getattr().

When you post snippets to be translated it's better to post whole little programs that can be run.
I presume you point was to show a Python code like this:

class Foo:
    def __init__(self):
        self.a = 10
        self.b = 20
        self.c = 30
    def all_attributes(self, attributes):
        return [getattr(self, c) for c in attributes]
f = Foo()
print f.all_attributes(["b", "c"])
# prints [20, 30]

If the names of the attributes are known at compile time then there are short enough ways to do the same thing in D.
If they are only known at compile time you will need much more complex solutions, using external libs that use run-time reflection, but it's for experienced users, I presume (in the future the D standard library may add such run-time things, they are possible in Java too).

I can show you a solution for the version where names are known at compile time, if you want, but it may require me a bit of coding. In most D programs you don't do those things.


> Is there also any construct similar to dictionaries?

Thank the Goddess there are, they are named with a quite long but more correct name: "associative arrays" (AAs), they are built-in and you can use them with a simple syntax:

int[string] aa;
aa["hello".dup] = 10;
etc.

Note that in many situations Python dicts are faster or much faster than D associative arrays. So in speed-critical points of your code you may have to invent creative ways to avoid using them, like using arrays of bools to represent the set, using enums, using sorted arrays with a binary search, etc. Often what's slow in D is fast in Python and vice versa (but very often what's fast in D is fast in Psyco too).


I leave your other questions to other people.

Bye,
bearophile



More information about the Digitalmars-d mailing list