mercredi 9 décembre 2009

unique 0.19 is out

Unique 0.19 is finally out! The new feature is in the browser. You can now select any text in the right pane and search for code similar to your selection. It adds to unique some kind of search engine... maybe I should add a search bar to make it more obvious.

Anyways... enjoy!

jeudi 5 novembre 2009

Considering unity

Does anybody here have experience with the unity game engine?
We could use it for one of our projects but we don't know how stable and extensible it is. If you can share horror or love stories, they would be most welcome.

Thanks!

lundi 19 octobre 2009

swig bindings of VTK : a call to arms

I don't know how common our situation is... We use VTK through it's Python interface but we also need to develop some algorithms in C++ and make them accessible to the Python runtime. The problem is that, as far as I know, the VTK bindings are not inter-operable with swig. The result is that we can allocate VTK data structures from Python but we can't give them to our C++ algorithm.

There are multiple solutions to this problem. The one we chose is to use swig to wrap our algorithm *and* VTK, in two different but inter-operable modules.

We will start by wrapping and testing the parts of VTK that we need right now, but if other people out there have a similar need perhaps we could collaborate and come up with better bindings.

So... is there anyone interested in participating in this not-yet-born open source project?

dimanche 4 octobre 2009

version control for media

Here is a nice idea : http://alumnit.ca/~apenwarr/log/?m=200910#04

I don't know of a version control system that works fine with lots of big files. Maybe this guy's idea will be implemented and allow git, mercurial and bazaar to become better systems for developers and artists working on media-rich applications.

vendredi 11 septembre 2009

VLAM is hiring!

We are looking for a junior developer.
http://www.vlam.ca/emplois/offre_emploi.pdf

dimanche 19 juillet 2009

I need feedback!

Unique users : I would really appreciate some feedback. Please take ~30 seconds and fill in this survey.

Click Here to take survey

Thanks!

lundi 15 juin 2009

unique has a browser

The last few releases were mostly about the new browser. The idea is to be able to spot right away where are the file with the most obvious duplication. Once you know where are the problem files, you can launch a pattern search in the right direction.

If some files displayed in the browser are not actually problematic (3rd party, build artifact, ...) you can right-click to hide it. The color of the labels will be renormalized automatically.

The browser also displays metric when the root node of the tree is selected. You can think of it as an anti-SLOC metric. People keep using SLOC as a productivity metric, keeping track of how much bloat is in those Source Line Of Code should give a better idea of the work done and the refactorings ahead.

You can always get the latest version on sourceforge : http://unique.sourceforge.net/. There is also the freshmeat page that's always up-to-date : http://freshmeat.net/projects/unique.

jeudi 11 juin 2009

C++ interview questions/inspiration - part 4

One, two, three

This is part 4. You can read the first three here :

Part 1
Part 2
Part 3


This fourth question is the bonus.


I didn't get to ask it very often. There is never enough time in an interview, that's why I prefer to have a small number of good questions. The questions need to be orthogonal and good predictors. This fourth question is not a very good predictor. Almost every candidate will flunk it. That's why I ask it last. Since the other three questions are good predictors, I often abandon before the fourth question.

Having questions that are good at detecting bad candidates is not enough. Interviewers often forget that interviews work both ways. Candidates judge companies too. It's very frustrating to leave an interview without having been asked at least one difficult question. If the candidate can't answer the difficult question, it's no big deal. If he succeeds, then you have learned something very important : it's a keeper.

The statement

Write a smart pointer. In the general case, it shall only keep a reference to the pointed object. If the pointed object's class inherits from IRefCountable, the smart pointer shall call the AddRef and Release member functions.

In case of silence

If there is an uncomfortable silence, ask more specific questions. What is a smart pointer? Do you know C++ templates? Have you ever used boost? Boost::mpl?

Runtime vs compile-time

Most candidates will try to use dynamic_cast. Does he know what are the limits of RTTI? What if the pointed object is an int?

vendredi 15 mai 2009

unique is getting faster

Version 0.8 is out and it brings serious improvements. I worked a lot on search speed and you will see the difference - it's a lot faster. Also, the new search wizard lets you choose files by type. The UI still sucks, but it's not as bad as it used to be :-)

Give it a try and tell me what you think about it!

http://unique.sourceforge.net/

dimanche 3 mai 2009

unique : now usable

I have just released unique 0.3. The big changes are in the UI : the match results are now displayed using the source code as it is formated in the files instead of a flat list of tokens. It makes all the difference in the world :-)

The search process is still slow for projects that are not tiny, I'll see what I can do about that. I do have a few ideas on how to fix that - can't wait to see how they work out.

https://sourceforge.net/projects/unique/

mardi 28 avril 2009

unique 0.2

Python source files are now processed more intelligently : tokens within comments are now ignored. Also, the filtering procedure has been improved a bit. You should get less repetitive results... of the repetitive patterns in your code :-)

get it from https://sourceforge.net/projects/unique/

dimanche 26 avril 2009

unique

Last weekend I wrote a little prototype to help me find patterns in my source code. It was a little python script. This weekend I revisited the script and transformed it into a small wxpython application.

You can get it from http://unique.sourceforge.net/

I labeled it as pre-alpha. It's really only a prototype. Ugly and bare-bones.

Ideas, bug reports et compagnie are all welcome.

mercredi 15 avril 2009

The evil of long-lived branches

Long-lived branches make good practices bad.

When coding in a branch that will eventually be merged, it's a bad idea to refactor. All the global changes required to correctly implement the feature you need to code will send lines flying all over the code base and there is no VCS capable of dealing with that automatically.

I mean, the VCS will be able to apply the changes you have made to some other codeline, but the changes done in the branched code that has been moved & refactored won't be merged properly.

Because you are on a branch, you can't code as local as possible anymore. You can't, because you won't be able to refactor when you will need to re-use this local code. You need to know in advance what will be re-used and how. That sends all those agile tricks out the window. Overdesign becomes the only solution. It means that the quality of the code is getting worse every day those branches are maintained apart. And if this situation lasts for a couple of months, it comes to a point where you don't even want the different branches to be merged anyway.

Features go in the mainline, stabilization in a short-lived regularly-merged (towards the mainline) branch. Doesn't it make sense?!

lundi 13 avril 2009

What is Lisp?

Confusing. Misunderstood. Lisp is plural.

Is it fast? Yes and no - it depends.
Isn't it old? Almost the oldest. But it's not a bad thing because it never stopped to evolve. New doesn't mean powerful, by the way.
Is it object-oriented? If you need it to be, sure. Even when it's not, it is.
Is it only good for research? It's reliable and fast, but not always. It has huge libraries, but not always. It's been used in big commercial systems, too. It sure is good for research, but it can also be used commercially.

Lisp sure is hard to explain briefly. But I think I found a way to keep it to a minimum when I'll have to say something about Lisp to my future collegues.

Lisp is syntax.

The only constant between the various dialects, platforms, interpreters, compilers... is the syntax. I used to repeat that lisp has no syntax. That may be true, but if everything else is blurry and contradictory about lisp, you end up with lisp being nothing and everything. It's nothing because it's only syntax and it has no syntax. It's everything because that nothingness of a syntax is fully programmable - and people have made everything with it.

Please pardon this nothing-of-a-post. I am myself trying to understand what my new favorite programming language is. If you can light the lantern of the newb that I am, go ahead - flame at will :-)

C++ interview questions/inspiration - part 3

Back to basics

Early exit is a nice and simple optimization strategy. If you are designing an interview algorithm to help you select great hackers, you can expect most candidates to fail the test. That's why you should try to sort your interview questions. By putting the better discriminants first, you will know sooner if the candidate is not quite as good as you would like him to be.

Knowing how good the candidate is early in the interview does not necessarily mean asking fewer questions, it means making the most of the little time you've got. If the guy looks like a super star you will want to skip one or two easy questions and get with the fun stuff. With super stars, it's the interviewer that has to show how good he is. Stars like to be asked tough, relevant questions. An easy interview indicates that anyone could get the position - and that the 'winner' will be surrounded with mediocre coders.

All this to say : don't focus on this 3rd question if the candidate looks like a star. Don't skip it entirely either, it's not that bad a discriminant. You definitely want to be sure that everyone that works with you can answer it straight, it's just not very challenging to experienced C++ programmers.

The feature presentation

a) What is printed on the console after the execution of this program?
b) What would you have done differently?



#include <iostream>


struct animal
{
~animal()
{
std::cout << "bye\n";
}

virtual void print()
{
std::cout << "I am an animal.\n";
}
};

struct bird : public animal
{
~bird()
{
std::cout << "bye bye birdie\n";
}

virtual void print()
{
std::cout << "I am a bird.\n";
}
};

void print( animal a )
{
a.print();
}


int main()
{
animal* a = new bird();
print( *a );
delete a;
return 0;
}


Low level

Can he spot the obvious errors? The print free function taking its argument by copy. The destructor of the super class not being virtual. Can he explain what the default copy constructor does? Does he know how to disable it? What about the assignment operator - did he think about it by himself? Virtual member functions - how do they work? What happens if the derived class's destructor is specified as virtual but not the super class? What if it's the other way around? Ever heard of a vtable? A vpointer?

High level

Will the candidate only worry about the low level details or will he think about the design globally? Does he know his sacred books? Can he actually recite Meyers and say "Make non-leaf classes abstract". Why make the super class's destructor virtual if there is nothing to free? Program in the future tense, of course.

Dazed and confused

Only the best will be able to speak about high level concerns easily, others will need a little help. You can help them with a derived example

int main()
{
animal* a = new bird();
animal other;
*a = other;
print( *a );
delete a;
return 0;
}
Is it sending them on the wild goose chase of virtual assignment operators or do they know better? It's ok to need a little help - it's not ok to become confused and disoriented.

Stay tuned for the next episode - it's a tough one.

Update

Part 4 is now available.

jeudi 12 mars 2009

The design of VLAM Compyle - the slides

Tonight I gave the presentation "The design of VLAM Compyle : A tower of languages from python to C++ using scheme" before MSLUG. A special thanks to Guillaume for inviting me.

For those who didn't show up (you should have, MSLUG is a fun group - plus, we were happy to have pythonistas join us from Montreal Python) all is not lost! You can get the slides. Also, I'll be happy to answer questions you might have.

Bonne nuit.

jeudi 5 mars 2009

How Compyle works

I will give a presentation before the Montreal Lisp/Scheme User Group about the design of VLAM Compyle.

Title : The Design of VLAM Compyle : a tower of languages from Python to C++ using Scheme
When: Thursday March 12th 7pm
Where: Room 3195, André-Aisenstadt Building, Université de Montréal, 2920 chemin de la Tour
Alternative title : VLAM Compyle ; a strange, erotic journey from Python to C++.

Come to meet hackers, stay for the beer. Venez en grand nombre.

mercredi 18 février 2009

Throw those error codes out

What to answer when asked to justify your use of exceptions:
  • It makes the main flow of the program obvious
  • It's the only sane way to signal an error from a constructor
  • It avoids partially constructed objects
  • You can't avoid them anyway
  • The information carried by exceptions is better structured than error codes
  • Error codes don't scale, exceptions do
It makes the main flow of the program obvious
When using exceptions, you don't need to check every single function call for error condition. This removes a lot of repetitive, useless code that gets in the way when trying to understand what is the first purpose of a single piece of code.

It's the only sane way to signal an error from a constructor
You could choose to only have useless constructors and init methods on every class... and you'd be wrong to do it. init methods are often the result of an inadequate error management strategy. More on that later, for now it should be clear that constructors don't have return values, and if you give a constructor an output parameter, you are in a fight against the language you can't win.

It avoids partially constructed objects
This one is huge! People underestimate it - big time. A good deal of what makes a class difficult to design & maintain is the number of states its instances can have. If any member of a class can be either constructed and non-initialized, constructed and initialized, constructed and partially initialized, constructed and uninitialized and , finally, destroyed.... what was I saying? Oh yeah, if any member can be in any one of those states, you are in trouble. You get destructors that are impossible to write, you have live objects everywhere in your system that are time bombs. Ever seen code like this?




if ( is_init() )
{
do_it();
}
else
{
return E_FAIL;
}


That means that the object can be in an invalid state. The class is not doing its job : the class's invariant is ill-defined. You don't get that when you use constructor with exceptions.

It all makes sense when you consider how members initialization/finalization works. First, members are destroyed in the reverse order of construction : it makes sense. When members are constructed {that's before the body of the parent's constructor begins its execution}, if the Nth member's constructor throws, the previous members {those that are fully constructed} will see their destructor called : it makes sense. If the Nth members fails, the destructor of the following members won't be called : that is very useful.

And memory leaks? If you have this :

my_object* obj = new my_object();


and if the constructor of my_object throws, the memory allocated by new will be freed automatically! No leak! :-) Of course, if would be a good idea to use some kind of smart pointer because if this object's constructor won't fail maybe something else will throw before the call to delete.

You can't avoid them anyway
new throws. The standard library throws. Boost throws. The world throws. Accept it. You not throwing does not spare you from writing exception-safe code.

The information carried by exceptions is better structured than error codes
It's easier to choose the right exception class when throwing than to structure error codes returned by functions. You will find tons of functions returning an int as an error code, I hope you will find a lot less functions throwing an int :-)

Error codes don't scale, exceptions do
Error code management implementation size grows with the number of functions called. Exception catching is pretty much O(1) and exception throwing implementation is proportional to the number of possible failed postconditions, I don't see how you could do better than that.

Shit happens. For the love of code, throw the shit out.

dimanche 15 février 2009

One possible path


VLAM will soon hire an intern. This brings a host of questions about cv selection, which school to choose, the interview process, etc. What interests me the most at this point is how to educate a junior programmer up to the point where we will be able to trust his code.

One possible path I think can work is the one displayed on the left.

Procedural

VLAM is a real-world software production environment and we need our programmers productive right-away. I find that even if functional programming has a definite mathematical beauty and simplicity, juniors don't get it right away. They do get that variables can refer to different values as the program is executed.

On a very practical note, we use 3rd party software that have very procedural interfaces. Procedural programming is the basis, the starting point and the common denominator. I hope I won't actually have to teach basic structs, unions, file handling, printf and C function pointers ; but if I have to, I'll try to get it out of the way right from the start.

Object

Inheritance, overloading, overriding, constructors, destructors - a junior coder has to master all of that before he can tackle exceptions (with of course exception-safe software design) and functional programming. Object-oriented programming is not a goal, but it is full of very usefull tools. Please, for the love of gods, don't stop here. Don't end up with "object-oriented programmers". Teach juniors patterns, so they can detect and factor them out in the future.

Key concepts :
  • The construction, allocation, destruction and deallocation of objects
  • Overloading, overriding
  • Multiple inheritance (and the diamond of death)
  • Patterns
Books to read :
  • The effective C++ series
  • Agile Software Development, Principles, Patterns, and Practices

Contracts, error handling and exceptions

I won't go on here about why you should use exceptions - that can be the subject of another post. Needless to say, proper error handling, asserts and exception safety is very important. Unfortunatly very few programmers in the real world are able to write code that won't leak or fail miserably when not everything goes as expected.

Key concepts :
  • RAII
  • asserts & contracts
  • try/catch
Books to read :
  • The exceptional C++ books
Functional

By this point, it should be clear to the new programmer that it's easier to write correct, extensible code when it's stateless. If C++ is your main tool, now is the time to fully understand how to use boost::function and boost::bind.

Key concepts :
  • Closures
  • Declarative-style programming
Books to read :
  • Structure and Interpretation of Computer Programs
Generic

This is a big one. Templates in C++, generics in Java and C#. They can be as painful as they can be useful. You absolutely need to cover object-oriented programming before, because you will need all the tools of classes to actually implement to opposite idea : the separation of algorithms from data structures.

Key concepts:
  • Runtime vs compile-time
  • SFINAE
  • Code generation
Books to read:
  • C++ Templates - The Complete Guide
  • On Lisp
  • Modern C++ Design
Scripting

Many would start with scripting, and yet I put it at the end. I don't mean that a junior programmer should wait to learn python or ruby until he masters C++ templates - quite the opposite. I think juniors should already know a scripting language before you hire them in the first place. I'm talking about the integration of scripting in applications.

After a programmer has suffered through C++ templates, once he understands what it take to write statically-typed reusable code, he is ready to bridge the gap between static and dynamic languages. Swig is no easy piece of cake, but if it allows you to write most of the code in a sane language, it's a small price to pay!

Key concepts:
  • Embedding
  • Foreign interfaces
  • Domain-specific languages
Any book suggestions?

mardi 20 janvier 2009

functional abstraction of data members with boost::bind

I just wanted to share a little trick I learned some time ago : you can use boost::bind to transform pointers to data members into functors.

For example, if you have a struct that looks like this :


struct my_struct
{
explicit my_struct( int value )
:m_some_member( value )
{
}
int m_some_member;
};


You can use boost::bind( &my_struct::m_some_member, _1 ) as a valid functor that will take an instance of my_struct as a parameter and return an int.

Admit it, it's pretty cool :-) You don't have to write the getter, bind will generate it for you.

What this kind of technique does to code readability is a matter you have to consider if you want to use it in a professional environment... I myself would most definitely write the getter in the vast majority of situations.

It's always fun to close with a little program that shows I cared enough to test the subject prior to publication ; here it is


#include <iostream>
#include <algorithm>
#include <vector>
#include <boost/bind.hpp>

struct my_struct
{
explicit my_struct( int value )
:m_some_member( value )
{
}
int m_some_member;
};

struct printer
{
typedef void result_type;
template< typename T >
inline void operator()( const T& anything )
{
std::cout << anything << std::endl;
}
};

int main()
{
std::vector< my_struct > my_vector;
my_vector.push_back( my_struct( 0 ) );
my_vector.push_back( my_struct( 1 ) );
my_vector.push_back( my_struct( 1 ) );
my_vector.push_back( my_struct( 2 ) );
my_vector.push_back( my_struct( 3 ) );
my_vector.push_back( my_struct( 5 ) );
std::for_each(
my_vector.begin(), my_vector.end(),
boost::bind( printer(),
boost::bind( &my_struct::m_some_member, _1 ) ) );
return 0;
}

samedi 17 janvier 2009

The selfish idiom

This is yet another post inspired by neodarwinism.

Code duplication happens all the time, no programmer doubts that. Because duplicating a piece of code is easy as hell and initially very cheap you quickly get yourself into some kind of a living mess. Big code bases do have a life of their own and the forces driving it are most interesting.

What makes a code fragment successful? It's like our own genes, it has to be reproduced at a high rate without copying errors. When that happens the replicating idiom slowly invades the code base. A growing number of similar duplicates increases the probabilities that one of them will be noticed by a programmer and copy-pasted once more ; so there is a positive feedback loop. Even if all programmers will tell you it's bad practice to help a piece of code multiply, when a specific instance of an idiom is all over the place it becomes standard practice. Give it a few more months, and it's a local 'best practice'.

The fragments of code that get copy-pasted are over-represented in our code bases... that says almost nothing about them. After all, they don't really replicate by themselves, they need our help. All these little code samples must have some kind of mind controlling power to force us to do their bidding. Successful code knows how to exploit our pride and laziness. I think that one of the super-powers self-duplicating code have is incomprehensibility.

survival of the misunderstood

That was the original title of the post. Control-C control-V is the standard prayer of our cargo cults. It's also the fertility dance that our code gene overlords make us do on those last-night hacking sessions. We get ourselves in a caffeinated transe and dance the dance of life!

Actually, the whole process is celebrated in a long mass. First we have the high priest creating the original code, with the original sin hidden inside of it. Then it's presented as an offering to a less experienced follower, that will a little while later pass the good news to colleague. It's very important that the followers don't quite understand what is going on inside the code, or else they might be tempted to factor it as a function and put an end to an evolution branch. The use of global state, counter-intuitive interfaces and weird 3rd-party libraries are all on the code's side.

how to kill it

What do we do now? It's very tempting to simply say "writer simpler code" ; but that would be very wrong. Of course you should not write code that's needlessly complicated, but stating the obvious never helps. My point is that there is very often a true need for the complexity we put in code. The complexity in good code simply represents the true complexity of the underlying problem and helps prevent code duplication. Otherwise you get simplexity.

There are two players in this game : the code and the coders. If we can't simply make the code simple, maybe we can make the coders better. After all, this high priest that created the original sin probably understands a good deal of it. He should work more at explaining his creations to his followers, and put a little less time in changing the colors of buttons, documenting, or whatever the boss of his boss thinks is valuable, billable hours.

jeudi 15 janvier 2009

Beauty in code

We should write beautiful code.

Saying that of course begs the question, what is beautiful code? And I won't answer it... not really. We should write beautiful code because we are equipped with hardware that can tell really really fast if something is beautiful.

Beauty is not useless

Without getting into the usefulness of live, physical beauty is synonymous with sexy for really good reasons. It is supposed to be an indicator of health in us, humans. Facial asymmetry, for example, can be an indicator of brain damage in early life. Someone with a koala face has more chances of being healthy. I am not sure of that at all, but for the argument's sake, let's say it's true. {When you think about it, beauty is not in the eye of beholder. It's in the dick of the fucker :-) }

So, should we abandon the use of our consciousness in favor of our guts when programming? {Let's call that Colbert style} Kind of, I guess :-) It would be more fun for the guy creating the new code, that's for sure!

We can do something a little less stupid by teaching us what should be beautiful code. But how?

The first thing to do is to reject beauty as criteria when programming and conducting code inspections. There is no contradiction! If you surround yourself with code you feel is beautiful, than you get beauty for beauty's sake - that's circular and retarded. You should surround yourself with code that's right, with the hope that in time you'll get used to it. Familiar code quickly becomes beautiful.

If we ever get to the point where ugly code is probably wrong, life will be sweet! Coding will be so much easier - but don't get comfortable! You'll still have to refrain from rejecting code on the basis of ugliness, or your sense of beauty will drift and once again become your worst enemy.

dimanche 11 janvier 2009

C++ interview questions/inspiration - part 2

So, the candidate has given an ok answer to the first question and/or you feel they deserve a second chance to impress you. I looooove this second question. It can really show how much of a professional the candidate is.

Here is the question :

Read the following program (the code is at the end of the post).

a) If the second dynamic memory allocation fails by throwing an exception, what is printed on the console?

b) Where is the bug in the application ; how would you fix it?


I love it because there is fun to be had for everyone. If the candidate is kinda junior, make sure he can tell the difference between the objects that are dynamically allocated vs those that are allocated on the stack. If the candidate can't tell the stack from the heap, you can skip the rest ; it's hopeless.

The key to the first part of the answer is to know that the members of an object are initialized in the order they are declared in the class, not in the order of the initialization list. The door class is written with that in mind. All the rest is straightforward for the first part of the test.

The question b) is much more interesting. The idea here is to make sure the candidate understands RAII. Bonus if he can mention it by name, but that's not what is important.

A senior programmer will jump on the memory leak like a wolf on a sheep, but others might not. I suggest you don't fail those that don't get it right away. Ask them if they know what a smart pointer is ; if they ever used one. If you can get someone to say that it's a good idea to use boost::scoped_ptr in this case, it's a keeper :-)

I also always ask the hidden sub-question c) What's the difference between boost::shared_ptr and boost::scoped_ptr ; and what is wrong with std::auto_ptr? There is no such thing as a senior C++ programmer that has never heard of boost. Call me elitist all you want, you won't be able to convince me otherwise.

Now, my favorite interview questions always allows exceptionnal candidates to distinguish themselves. In this case, if you get a pretty good answer to question b), repeat the question a) with the fixed program. It's harder, because the candidate has to know how destructors are called in the stack unwiding process. Once again, if he can't quite do it, help him a little. Tell him "The destructor is called if the object was fully constructed, and an object is fully constructed when the flow of the program leaves a constructor normaly." ; it should help.

If you ever try it on a candidate, tell me how it goes :-) I hope it will be as usefull to you as it has been to me.

#include <iostream>

struct door_handle
{
door_handle()
{
std::cout << "c-door_handle\n";
}

~door_handle()
{
std::cout << "d-door_handle\n";
}
};

struct window
{
window()
{
std::cout << "c-window\n";
}

~window()
{
std::cout << "d-window\n";
}
};

struct door
{
door_handle* m_door_handle;
window* m_window;
door()
: m_window( new window() )
, m_door_handle( new door_handle() )
{

}

~door()
{
delete m_window;
delete m_door_handle;
}
};

struct car
{
door m_left_door;
door m_right_door;
};

struct acura : public car
{
};

int main()
{
try
{
acura some_car;
std::cout << "we have a car!\n";
}
catch( ... )
{
std::cout << "error\n";
return 1;
}
std::cout << "bye-bye\n";
return 0;
}


Update

Parts three and four are now available.