Brendan wrote:skeen wrote:Whenever I have to solve a specific task (say implement a code generation phase) in some programming language, my approach is usually (simplified);
My approach is roughly similar. The main difference is that I try to find better ways of doing things than existing ways. If users are involved, this means making it easier for real people (not "academics"), and if users aren't involved this means making it faster, more scalable, etc. If something is written in a book, then it's just a starting point that needs to be improved on.
What I sketched out was the typical process, that is, when I'm not doing anything research related, but rather doing the somewhat mechanical process of solving a specific task.
When I'm working on my hobby OS or compiler; I do indeed try to find better ways to do things. I try to get rid of the old (and in with the new), because tying yourself to the standard way, limits your creativity, and originality.
Brendan wrote:
The other thing I do is separate design from implementation. Often I'll have the ideas rolling around my head for a week or more, write pages of notes, then finally (if appropriate) write down "formal" documentation or specifications. Then I'll try to forget it for another week or more and go back to the notes/docs/specs and try to find holes in the ideas and improve them more.
I don't start implementation until after design is done. Implementation is mostly a mechanical thing - converting a design into something the computer can execute. Because all the design is done beforehand I can concentrate on implementing efficient code. I mostly only use library functions as a way to access the kernel API (e.g. file IO, threads, etc). If I'm able to use generic things from a library (e.g. sorting, searching, lists, etc) then that mean my code is bad (I've failed to do things efficiently enough to avoid needing to sort, search, etc).
I actually use my implementation as a part of the design process, as it let's me experiment with more than the conceptual idea, this will sometimes help me notice serious flaws in the design, before I'm converting it to industrial strength, the main thing to notice in my list, is that the implementation I get, before refactoring it, is usually quite rubbish, as it's mostly hacked together, to make it work, and test the design.
I used to do the entire design up front, however I've come to find, that quite a lot of issues doesn't show up, until I start implementing, that may just be because of faulty design, but that's my way of weeding out bad designs. Also I'm affected by the entire scrum / agile development movement because of my choice of education.
However, the way I implement, it is not really a mechanical process, but rather a part of the design process. The act of converting the initial implementation, to an industrial strength one, is on the other hand, quite mechanical. As for using generic libraries; I usually just use whatever, when I'm in progress of writing my initial implementation. If I need a container, I'll just use a dynamic array, and change it later, if it turns out some other data structure would be better fit. (i.e. if it turns out i'm doing mostly inserts and deletes, and few lookups).
Brendan wrote:
For a simple example, how many people here use "strlen()"? To me, that's a sure sign that the code isn't good enough (I failed to keep track of the string's length in previous code).
I agree that 'strlen()' is an example of bad design, given that you can just keep track of the length of a string, or even have the compiler do it for you.
Brendan wrote:
skeen wrote:My point with this, is that I have a somewhat rigid approach to problems, and I want my tools to help me out along the way.
For the programming language tool, what I expect is;
I'd ask what tools you use for designing software, but I already know the answer because everyone's answer is the same (including mine). It's like there's a very important tool that should exist, but doesn't. By the time you get to implementation, you should be focusing on very small details, not the larger picture, but existing tools suck so...
While most people use the same tools, I must once again, recommend the clang toolkit, it has helped me out immensely in debugging hard to find errors. Also;
Brendan wrote:
For understanding assembly, syntax highlighting is nice (but entirely optional). There is nothing else that I'm aware of (e.g. no complex IDE with all sorts of features) because nobody ever really needed anything else. How many people would work on a large project written in C++ with nothing more than syntax highlighting?
I'm one of those people, that doesn't use a massive IDE, but rather command line tools, my trusted editor and scripts.
Brendan wrote:
skeen wrote:In most language, sorting just requires me to lookup the right name, e.g. 'qsort' or 'std::sort', however for these two, I have to spend time understand the arguments, which is unfortunate.
Sorting is like "strlen()" - if you need to sort something that already exists, then you've failed to do your job properly and sort it while it was being created.
If I wanted something to be sorted while creating it, then I'd use a data structure, which had the invariant that the data was always sorted. Then I wouldn't have to sort my data, however data structures with this invariant, comes at a cost, and as such it may or may not be what you need in the given context.
Brendan wrote:
skeen wrote:That being said, generics usually help me out, in terms of avoiding the reimplementation of standard algorithms, as I can simply use them with whatever type I like, with little hassle (i.e. implementing a comparator for instance).
I can't think of any standard algorithm I wouldn't "reimplement". Linked lists (and FIFO/FILO queues) and vectors are too trivial to bother with libraries. Hash tables I like to tune (get a good compromise between hash size and hash collisions for the data I'm expecting). Sorting I've already mentioned.
You state that linked lists, and vectors are too trivial to bother with, but in my case. I actually like not having to implement these, while I'm in the middle of implementing something else, and hence I prefer just being able to write vector<int>, rather than have to implement one.
Brendan wrote:
skeen wrote:Now as for performance, that is really rarely an issue for me, when doing a new implementation, as I'd rather have the code working first, before I start optimizing it, also having the code running first, helps me profile the bottlenecks of the code.
I never really end up profiling. In theory I should, but I've never been disappointed by my code's performance enough to bother.
I usually never get to profiling either, because it's almost never an issue with the performance when using standard containers, and algorithms.