Long time no see. Since I came back to France I did not take the time to post. I have/had some ideas of what to share but nothing big…
Why I don’t like Python even if I use it nearly every days.
The utf-8 support
Python2 has a poor support of utf-8. You can get some Encoding/DecodingError very easily.
In my school, every projects are corrected with a software I developed. It is responsible for gather the student project (on AFS, SVN, HG or GIT location) and make a correction. The problem is that the program entry may received data it can’t handle. When a student program is buggy it can print some unexpected character like some utf-8 characters that is interpreted as a multi-byte character and when the next one does not fit the requirement for a proper decoding, Python throw an exception… The cause is only because Python treat every data as string and it is dynamically typed.
I never tried Python3 but things seem better since a ‘new’ type will be present: the data type. Here is a better description that I could do:
http://docs.python.org/release/3.0.1/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit
The static scoping.
Python is slow, it is not a secret but to improve the performances they statically scoped the variable. Here is an example:
>>> def test(): ... i = 2 ... def test2(): ... return i + 1 ... return test2 ... >>> test() <function test2 at 0x7f2c7af13a68> >>> test()() 3 >>> def test(): ... i = 2 ... def test2(): ... i = i + 1 ... return i ... return test2 ... >>> test() <function test2 at 0x7f2c7a9f4d10> >>> test()() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in test2 UnboundLocalError: local variable 'i' referenced before assignment
When the Python interpreter sees an initialization it creates a table attached to the function to allow a fast symbol resolution. But it does not handle the fact that a variable can come from a parent context like here. So you can’t do a closure in Python
A little bit of C++ meta-programming.
I like the meta-reprogramming (even if Lisp is better), but sadly I don’t use it often… The last week I had to do a program which checks if thousands codes are valid against an ISO specs. The problem is that there is no rules, only possibilities (i.e. if at index X I have the character I, at X + 1 I must have A, S, D or F). A very painful task but I was able to add some fun in it by creating a static template tree.
Here is the code:
template<class T>
struct cfi_level
{
char letter;
T next_valid;
bool is_valid(const char* cfi) const
{
if (*cfi == letter)
{
return next_valid.is_valid(++cfi);
}
return false;
}
};
enum
{
MAX_LEVEL = 11
};
template<int DEPTH>
struct _cfis
{
typedef _cfis<DEPTH - 1> ChildClass;
bool is_valid(const char* cfi) const
{
for (int i = 0; i < MAX_LEVEL; ++i)
{
if (current_level[i].is_valid(cfi))
return true;
}
return false;
}
cfi_level<ChildClass> current_level[MAX_LEVEL];
};
template<>
struct _cfis<0>
{
const char* letters;
bool is_valid(const char* cfi) const
{
return !*(cfi + 1) && strchr(letters, *cfi);
}
};
typedef _cfis<5> Cfis;
// the big static initialization. let as exercise for the reader
#include "array.cpp"
static inline bool is_cfi_valid(const char* cfi)
{
// c comes from array.cpp
return c.is_valid(cfi);
}
static inline bool is_cfi_valid(const std::string& cfi)
{
return is_cfi_valid(cfi.c_str());
}

