My Cygwin installation does nothing when I type "clear", it say it does not know this command or something. It is quite basic operation to be unavailable. Oh well, that's just life, nothing that a little googling couldn't help.
This blog's post clears up things for me : I need to install ncurses package. It is fixed now but I still think it should be available by default though.
Wednesday, February 27, 2008
No "clear" Command in Cygwin Default Installation
Diposting oleh
Hafiz
di
Wednesday, February 27, 2008
26
komentar
Label: system
Monday, February 25, 2008
The Useful "tail -f"
"tail" is a program in UNIX-like system to print a little part of the end of a file (it's counterpart is easy to guess : "head" to print the beginning instead). At first, I didn't find this program anything special, just some program that I think I might use someday when I need it.
I find a more useful use of it when quite a long time ago I try to setup my tv-tuner to work on linux , which is quite painful to do at that time. Thanks to one reference that on the net (which I lost the link, unfortunately) that use "tail -f" to view the change in log file in realtime (it was used to watch the loading/unloading of the driver to see the effect of different parameters, pure "fun" ;) ), I got myself one very handy tool to watch log file (or any file with the same nature) since then.
When you have trouble with servers or system in general, you could troubleshoot better with this. However, "tail -f" could be really handy for programming too. When you want to trace program as a work around when you have some problem to show them in screen, just print them to file and watch it's changes/appending in realtime and you can avoid having to scan the whole log file after-the-fact.
It's available on most of the system e.g: Cygwin for windows. So, you can rely on it most of the time.
Diposting oleh
Hafiz
di
Monday, February 25, 2008
0
komentar
Label: application
Wednesday, February 20, 2008
Refactoring to Make Code More Human Readable, a Little Example
I code a little tool in .Net today and need to initiate something different based on whether the second argument is given or not. The program would go something like (to protect the innocent, I'll use very generic name here) :
myProgram arg0
or
myProgram arg0 arg 1
First, doing the simplest things first, the arguments handling goes something like
1:
2:if (args.Length > 1)
3:{
4: //initiate something the standard way
5:}
6:else
7:{
8: //initiate diffrently
9:}
10:
Its works ok but the conditional above left something to be desire, so I refactor it by extracting checking argument length into function :
1:
2:if(!supportFileIsGiven(ref args))
3:{
4: //initiate something the standard way
5:}
6:else
7:{
8: //initiate things differently
9:}
10:
Suddenly the code become a more readable english. It tells more story and deliver meaning. Given a choice, I'll choose code with the style of the second one to work on anytime of day.
Diposting oleh
Hafiz
di
Wednesday, February 20, 2008
1 komentar
Label: coding
Tuesday, February 19, 2008
Java, C# and the Case of Inferior Look
Building application is a lot of work and dealing with low level issue of OS API makes it worse. Relatively high-level language like Java and C# (I haven't seen GUI-based on language like Ruby application widely used yet) could help to enhance productivity on this.
However, despite the already long evolution, those languages has not yet fully capable to give competitive result in terms of user interface. Java-based GUI is still looking inferior compare to natively written application. Even in Windows , where it seems to have the best integration, it still feel odd here and there. It's quite unfortunate since it's relatively good/easy language to build application on.
Then along the way come .Net (C#). This one is a little bit better, at least if what you are trying to do is developing things for Windows. It has the easiness of Java but quite native feeling of the interface. For quick application programming with fancy interfaces it provide what mostly needed to get the job done. It is still has some holes here and there, but fortunately for this one, the interoperability to native code is quite excellent with lots of third party component to fill in the gap.
All is not lost in Java side though since there's SWT to the rescue. I think people seriously looking to develop application in Java but still want to be competitive in the user interface department should put this into their toolbox. It still has some issues though, but it has good approach which lately Java has start to adopt in recent releases, i.e: more native widget rendering.
There's a tradeoff in doing abstraction and generalization as we see in the case of programming in VM-based language. It create some gap in areas outside the intersection and generalization that is being taken. But the recent effort has getting closer to close/bridge those gap.
There's another path someone could take to avoid having "inferior" look to his app but still a little more productive than having to access OS API directly. It's the bottom up way : C++ Wrappers. Instead starting with easiness/abstraction and move down to take care of nativeness details, you could start with having nativeness first and work on having easiness/abstraction. There are lots of various C++ wrappers out there that could help with this e.g: QT.
Take your pick then, it's the world full of options and you don't have to always use something suboptimal, given by the standard lib, for the look if you don't want to. That being said, I still enjoy JEdit, Freemind and JUDE despite their look feels out of place a little bit. So, I guess the substance is still the king although the look could really help too.
Diposting oleh
Hafiz
di
Tuesday, February 19, 2008
0
komentar
Label: miscellaneous
Monday, February 18, 2008
CScopeFinder, JEdit Plugin for Rapid Code Searching
I use JEdit as my "support" IDE. Sometime I can't do all things in main IDE and sometime situation require side-by-side comparison. There are the kind of situation, among others, that I use JEdit for. It requires me to setup plugins that help in searching symbols and tracing relationships. One of them is CScopeFinder.
The setup is using a very nice built-in PluginManager in Jedit, you just need to look for CScopeFinder and install it. The tricky part is on cscope binary dependencies (the root of source tree to be searched need to be run "cscope -b -c -R" first). In Windows I use cscope binary from here. It has some bugs that confuse me at first but, long story short, it turned out that it has bugs in outputting root path of the resulting csope.out : it add double quote after that path with no matching double quote before. The first line looks like something like this :
cscope 16 e:\the\path\here" ....
I just need to edit the file, delete the offending double quote and it is usable afterwards.
The usage is not as tricky as the installation though : just select the symbol you like to search (double click on the word will do), right click and choose "Find This C Symbol" and the result will popup which has more contextual information then generic searching. It also has "Cscope Stack" window where it keep the result of it's finding to be refered to more conviniently.
I usually use it in combination with the, also very powerful, built-in HyperSearch in JEdit.
I find this plugin quite handy when I work through unfamiliar code which I have to refer to without opening up another instance of IDE just to get the cross searching capability or adding more burden to the already-crowded currently running IDE. It's a bit outdated (the plugin as well as the csope-win32) but still useful nonetheless.
Diposting oleh
Hafiz
di
Monday, February 18, 2008
1 komentar
Label: application
Friday, February 15, 2008
Pocket Freemind, Freemind on PocketPC
PocketFreemind is the first open source (and hopefully not the last :) ) project I've joined and the only one I took so far. I took a plunge since I do many critical stuff in Freemind and need them to be mobile. The state of PocketFreemind at that time is quite usable but it missing some feature that is quite substantial to the personal-semantic-convention that I use in the desktop version e.g: red and green font, icons.
I took some time to catch up and start adding the needed feature (thanks for Peter Carol that has started this project and already code some quite easy-to-work-with codebase). It was really fun and interesting (got exposed to windows mobile development). After I got the very-needed feature I needed, I took the time off due to, as usual, work and life.
I am still looking forward for some more spacious time to start coding it again. There are still some features I had floating in my mind that I really like to have it implemented and there's also the Freemind 0.9.0 support e.g : node with attributes that will be really interesting to explore.
It still uses what's is provide by .net regarding TreeView and Node, that's why you still see something funny like square block on node without icons (actually, without node it will be blank, but I add a blank square icon for node without icon to help with the visual since it will look really wacky without it). More exploration on doing custom drawing of node could, at least potentially, make things prettier.
So, if you got the need to sync your freemind file with your PocketPC, give it a try.
Diposting oleh
Hafiz
di
Friday, February 15, 2008
0
komentar
Label: application
Tuesday, February 12, 2008
Budget Time with Time Block
How do we materialize our priority in our daily life? in the case of money people make budgets, in the case of time I think make routine time blocks would do it.
When we spend without budget and bookkeeping we usually end up wondering where the hell those money gone.Similarly, without allocating exclusive time to do something routinely I don't think we can feel sure we have already "walk our talk". When I say coding should occupy 80 percent of programmers time, then I would need to prepare an 80 percent of my working time to do just that with as minimum fragmentation as possible. For other responsibility I would then need to allocate another block to do them in batch thus minimize the overhead of context switching.
Here's an example of the time blocks :
- 9:00 - 12:00. Code : the most critical tasks
- 13:00 - 15:00 Code 2 : more explorative ones or continuing stuff from block 1
- 15:00 - 17:00 Mails and anything else
This requires that our tasks be pooled into certain system based on the block/context e.g: GTD, so when we are in certain block we pick a task only from that pool. Anything come our way when we are in certain block should be pooled into this system to be done later on it's block comes.
Of course, like diet, this would require someone to be committed to it if he want to see some difference. But unlike diet, people won't get fat if they cross the line, at least not directly (you know : missed deadline -> stressed -> eat a lot -> gain more weight). However, if you commit in doing it other people will start to pickup your rythm and will adapt to it and it will make things easier by time.
Allocate exclusive time block should be natural if someone is sure about what he think is important. It won't always means easy but the gain is worth it : steady progress in the area that is important can become something more common and not something that come by occasionally.
Diposting oleh
Hafiz
di
Tuesday, February 12, 2008
0
komentar
Label: effectivity
Monday, February 11, 2008
Vista ATI Display Driver Problem
Update (2008-06-08) : I updated to version 8.476.0.0 (28/03/2008) and the problem is no longer there. Case closed.
I have used Windows Vista several months now. Despite it's several shortcomings (and bad reviews around the net) it is quite usable in my case. However, one thing still really annoy me : the ATI display driver problem. Occasionally the screen would go blank and the message below showup :
I usually can get back to work fine after it happen. However, using recent drivers the problem is really bad, the driver reset would go on several time and ended up with the blue-screen-of-death (haven't seen this for quite a while before using Vista). I am currently stuck with driver version 8.390.0.0 which come from June 2007, otherwise the bluescreen would appear twice a day minimum.
I have tried any appearing driver updates, so far it's not solved yet. It's not that a major problem though, I can still work fine (old driver that works is enough for now), it's just that I think I can sympathize better with people having problem with this OS :).
Diposting oleh
Hafiz
di
Monday, February 11, 2008
0
komentar
Label: system
Wednesday, February 06, 2008
Application Level Programming in C++
C++ is a language that you could twist to almost any form of programming (with a cost, of course). You could program with low-level-ness that is only one step away from assembly language and on the other extreme you could build the huge common-user-centered application with all it's bells and whistles. Here I would like to elaborate about the later.
Now that we have Java and C#, it's hard not to think application-level programming without getting them into the discussion. Doing the same thing as C# code would then mandate the C++ programmer to at least review factors that makes them widely-adopted (and even better to try them deep enough to really "get" it) and take some lesson.
That being said, I think to be able to compete in application-level programming using C++ i.e: use C++ to get the performance and flexible lower level API but still able to avoid getting stuck and wasting time in micro problems (pointer anyone?), is to "emulate" the virtual machine e.g: JVM, .Net.
Clearly, what I mean by emulating is not to make another VM or code a scripting a language (most language written in C/C++ anyway). What I mean is to prepare the environment, libraries, framework, tools, build system, etc.. so that you only concern with matters that most people using language like Java is concern too with other thing handled by your manually-crafted VM. Those things should be assimilated, glued and setup with rigidness to the point that we can take them for granted to be working and the use of them is made semi-automatic in our daily typing/coding.
With existing components available now, you could already emulate almost what the Virtual Machine offer albeit with a little more hard work on your part. If you think the gain is worth it then many things already available to you.
For example, using naked new and delete can be considered suicide if your aim is to make an application (hint : boost::shared_ptr). Iterating collection using Functor or using old-style for (incrementing index) would make you hard to match readability of C# code (hint : boost::lambda). Manually editing Makefile if you aim to make big application could cripple your speed when something messed up with the makefile along the way or it become an unmaintainable monster (hint : CMake, Rake, Ant). There are already libraries and tools to help you match those kind of things that many other offer in VM-based language.
Just because you have to use C++ does not mean you can not use conceptualization, abstraction, modularization that is used by higher level languages and put them to good use in your own case and situation.
Diposting oleh
Hafiz
di
Wednesday, February 06, 2008
0
komentar
Label: coding
Tuesday, February 05, 2008
Track Coding Session with Freemind and JEdit
Coding session is an activity that could fill your brain resources pretty quickly. You need to hold a lot of things in your head at one time. I find this tiring and stressful if not being helped by some tools to act as process scheduler and/or swap "device" so my RAM could have lots of space for the micro task.
I use mainly Freemind and JEdit for this (in conceptual level : a Mindmapping and Text Editor application) with pencil and paper ready for emergency. The use of Freemind is basically similar to what I wrote about tracking internet search only in this case it is used to track task, subtasks, subsubtasks, subsubsubtaks while coding. JEdit is handy as a "buffer" for codes, notes and other things that is less hierarchical in nature.
Some trick I find helpful so far :
- Don't branch out too deep. Try to make spawned task as a sibling instead of a child of current task, if possible.
- Try to do one task within one hour or two hour max. Keep subtask/subtask, if any, within 15-20 minutes. I use Activity Timer gadget to help with this.
- Use shortcuts, colors, icons to make the overhead of entering/typing small but still maintaining clarity.
- Attach the elapsed time of a task for evaluation. It's a good source for better estimating later and for better divide-and-conquer skill. Here's my own convention look like :

- Dump code snippets, notes, deleted code to JEdit, it could be useful later. I also find this better, more flexible and more dependable than to rely solely on undo/redo of IDE.
Diposting oleh
Hafiz
di
Tuesday, February 05, 2008
0
komentar
Label: coding
Monday, February 04, 2008
Combining Trac and XPlanner
I wrote sometime ago about how using issue/bug tracker (Trac) and progress tracker (XPlanner) is really helpful, at least in my case. It will be really good if those two really integrated, but unfortunately it's not the case right now. We need to "integrate" them manually.
Here's the main conceptual merging I have made between them to support the concepts I am using :
Tickets is Story, Story is Ticket
From here on it's like directing the flow of detail that is stuck in Ticket in Trac, connect it and let it trickle down in to more detail through Story "hole" in XPlanner. Every Story is a Ticket being done.
We could have best of both worlds with this connection. On the trac side we have more strategic view of the Ticket/Story (Milestone, Roadmap, Wikis) and on the XPlanner side we have Progrress/Development detail regarding it (Burndown chart, tasks drilldown, assignments, timesheet).
Some useful mechanism regarding this :
- Make a wiki shortcut in XPlanner to Trac so in xplanner you could type something like 'wiki:ticket/555' or 'wiki:changeset/555' XPlanner and it's wiki system will link it to the Trac's entry. We could do interesting with this like make notes in Task entry that link to certain subversion revision.
- Use 1 to n mapping from Trac's Milsestone to XPlanner's iteration. Pick story to be done in certain iteration from it's parent Milestone.
- Let all the detail concerning the Ticket (notes, references, updates, troubles) updated in Trac to avoid duplication or confusion. Position XPlanner more for scheduling, timesheet and log-like notes.
Diposting oleh
Hafiz
di
Monday, February 04, 2008
2
komentar
Label: agile
Friday, February 01, 2008
Strip File Extension from Filename in .Net
Today I need to get a filename without the extension in .Net. It turn out that it's pretty easy. It's not so obvious from looking at MSDN (going through references for string and FileInfo give unsatisfying result). Being lazy to code this kind of stuff myself if I don't really have to, some googling get me more enlightening discussion.
Surprisingly, the line below return what I need :
Path.GetFileNameWithoutExtension(fileNameStr);
It's pretty straightforward and very convenient. It makes me wonder what people will make next, probably something like :
fileNameStr.AssumeThisStringIsFilenameAndGetItsNameWithoutTheExtension();
that would makes my work easier, although it probably would annoy someone else a little bit :).
Diposting oleh
Hafiz
di
Friday, February 01, 2008
0
komentar
Label: coding
Thursday, January 31, 2008
Testing and Volatility of Code
When does automating test worth doing and when it does not? one of the consideration I think the is volatility of the code.
The more volatile the code the more it is probably not worth automating, at least not directly. If you just code something to be changed not long after or will be changed quite frequently keeping it automatically tested will be costly. It is not a burden if it is only several dynamic part that we tested, but if there is a lot of them the accumulation of little frequently-changing tests that need to be maintained will be burdensome.
I know, if you use TestDrivenDevelopment, you make test first before any code. However, I think of it in conceptual level. You have to have test before any code, not to have The Test e.g: xUnit-based test. Your test could be in your mind and the value could be the one that your command line program print in console and you do Assert with the value in your mind. It's TestDriven enough for me and for not yet stable problem sometime I feel it's more flexible that way.
My concern here is on the word "automating" not on the TestDriven-ness. Automation is investment and it should be managed so that it gives us benefit more than it cost. Volatile code makes the tests volatile too, so lots of volatile code to test, lost of cost in changing/maintaining those test accumulatively.
There are a lot of solution for this e.g: test it indirectly through more stable code, but the main point is that we could test in a more efficient manner by paying attention to volatility of the code.
Diposting oleh
Hafiz
di
Thursday, January 31, 2008
0
komentar
Label: coding
Wednesday, January 30, 2008
Coding Tolerance
Regarding Coding Standard, Instead of following something resembling Coding Standard I see what I have been doing lately is more of from the other way direction : Coding Tolerance. With standard, you define what you want and then define how things should be to meet those. With coding tolerance you start with let things be the way they are and then review what you can tolerate and do refinement when necessary.
Coding Tolerance can be looked as a bottom-up, pragmatic approach to making guidelines in coding. With it, you do not spend time in advance to try to cover all possible things that would mess things up. Instead you allow codes to contribute as long as you can still tolerate it based on your knowledge, experience, situation and condition you try to maintain steady progress.
Tolerating does not mean you start with zero rules. You define only small, substantial guideline at the beginning and refine from there case by case, item by item and refactor/streamline the rules when necessary. You don't judge the code from your coworker or from certain libraries by rigid syntaxtual standard, instead you try to understand why they got the way they are and whether you can still accept it considering your goal. There are many learning experience you'll get from it.
The insights we get from tolerating certain coding style is not just we can go relatively faster in short term (since we focus on getting things working), but it is beneficial for the future too. We could get insights on better way of doing things that we will not get if we just forcing insisting that our way is the right way.
So, the next time you try to define coding standard, try to define it from the perspective of what you can tolerate instead of the usual structure, style, syntax oriented rule. It might give you lighter, easier rule to comply that is still effective.
Diposting oleh
Hafiz
di
Wednesday, January 30, 2008
0
komentar
Label: coding
Tuesday, January 29, 2008
Switch Between Analytical and Empirical Hat in Coding to Avoid Blocking
Programmers has two hat that he can switch around to avoid blocking when coding. Those two are the Analytical (thinking, elaborating and tracing logic) and Empirical hat (Debug, print and compare values). Without being aware of this, I find that I sometime spend too much time in one mode that if I just switch to another mode when things seems getting hopeless in the current mode it could be a lot faster. Being flexible in switching mode could speed up and ease up the problem solving process. It'll make things more fun too, almost like playing a game.
Being Analytical is when you review the structure and logic of program, class design, association, hierarchies, call sequence and finally find out what to do. Being Empirical is just give the program the input, trace, see the real numbers and values, and review the output.
Blocking in analytical mode is when you find reviewing the structure and logic seems to get you nowhere, the class seems ok, the function and logic looks alright but the output is wrong. Blocking in empirical is when the input and output does not reveal to you any pattern on insights on what's going on.
Our brain seems to need both concrete/empirical and conceptual input in problem solving. The empirical test could help us understand part of the logic that might not get into our attention when relying only on static analyzing. The analytical view could shed us some lights on the problems in it's substantial level that the output fail to give us any concrete things to work on.
In coding, when reviewing why something does not work, I usually start with analytical review and if it's not solving anything, I just start tracing, dumping values, debugging. Sometime in the middle of tracing and debugging I got another idea to review certain part analytically. I just need to remember not to push to solve the problem in one mode if it does not seen to bear fruit and start to see it with another perspective.
Of course, when both are fail, taking a break would probably the best thing to do. But that's another issue and would require another discussion. The point is to avoid being sucked by the problem and utilize different perspective to keep things in control and most importantly, to keep it fun.
Diposting oleh
Hafiz
di
Tuesday, January 29, 2008
0
komentar
Label: coding
Thursday, January 24, 2008
Agile and Effectivity : Two Game at a Time
On the book "Agile Software Development", Alistair Cockburn wrote that there are two game running in parallel when people develop software. The two game can be summarized as :
- Make code that work
- Keep the code workable
I see the two item above parallel with, if not an instance of, the concept of Production/ProductionCapacity (P/PC) balance in Stephen Covey's book "Seven Habit of Highly Effective People". And if you look around for more, many problem following the same model : using tool vs. learning the new ones, adding more hours in one language with experimenting with the new ones.
Defining Effectivity as balancing between P/PC is like defining EffectiveCoding as balancing between Coding/Refactoring.
Diposting oleh
Hafiz
di
Thursday, January 24, 2008
0
komentar
Label: agile
Wednesday, January 23, 2008
Track Internet Searching using Freemind
I've mentioned in the previous post that I used Mindmapping application to track my internet search in realtime. The reason is that the search can go out of hand if not tracked like this. We could end up spending hours looking at anything that caught our attention on the search result that is not too relevant to our current task.
Here's how, more or less, my "control center" looks like when I do a research-heavy task :
You've probably guessed the convention already : red for active item, green for done, small gray on notes.
I think the next step for after having a taste of how the searching in internet done and what it can gives us, is to use it with some kind of heuristic and a little discipline. This is just my current way of doing it and I find it quite useful to help focus on getting things done.
Diposting oleh
Hafiz
di
Wednesday, January 23, 2008
0
komentar
Label: effectivity
Monday, January 21, 2008
If You Want to Program in C, Use C++
There cases where C is chosen as a programming language. When this happen, I think it's better to use C++ with C style programming instead of using "classical" style one. This means use C++ as a Better C, an improved C for functional programming without it's Object Oriented and Generic Programming.
I have seen the code written in recent times that still use C strictly with it's old convention and. I think it's still makes sense if it's a maintenance/bug fixing work, but for new project I think we could improve readability, safety and more convenient coding time.
You could choose to use feature that only improve your typically-used structure like inline function to replace macro or use flexible declaration placement instead of having to declare all of them in the beginning. If you feel brave enough you could use more new stuff like references. You could even use STL's containers without harming your program's "functional-ness" (just use typedefs to hide those nasty template instantiation).
As a guideline, don't use what you don't understand or only have a vague sense of why behind certain construct. When you do, you'll most likely will get into trouble sooner or later.
You could program in functional-paradigm without having to revert to use plain old C these days, just need to get a little familiar with what C++ has to offer regarding it.
Diposting oleh
Hafiz
di
Monday, January 21, 2008
0
komentar
Label: coding
Thursday, January 17, 2008
Separate Collecting and Action Phase in Searching
One useful idea in GTD is to separate collection and followup/action step. It helps us to not caught up in reactive mode and loose sense of direction. I find this idea really useful when I do searching on the internet. It is even more critical in this matter since there are tons of things that could get you off-balance and distracted while searching things on the net.
First thing to do is to have map and tracking tools of what you need to do. It can be just your mind, but it's better to have helper tools like Text Editor or Minmapping application. Be clear on what you want and put an entry on each query you requested and track what you get from each. Jotting down the query you pass and track the result of each can be a useful trick to incrementally refine your search. The next is to do it in two separate steps : collection and action.
In collection step I only skim each of the links or page and drag them to to bookmark and/or scrapbook (see my post on setup firefox for this purpose). Along the way, when I find any unrelated but seems interesting I just drag them to tmp folder to followup sometime later when there's more free time. Then, when I think I have enough interesting things and the search result seems exhausted I continue with action step i.e: follow them up one by one in a more relax and more concentration on each.
I don't always do it in a clear separation or perfectly like the above, there's occasional time I just follow along with the chain of links. However, having mentally separate the process helps to get more of the links i.e: prioritize which to followup and avoid to get distracted. If we just get along, we might already exhausted and our mind distracted when we unconsciously missed a worthy one or don't have energy to followup anymore links ahead which could have a good info.
Internet is such a big source of distraction if you are not careful. But it will be a dependable servant when you have clear focus on what you want and structure and discipline in handling what it gives back to you. Of course, it's fun to surf for leisure but it's better not to do it at the time you intended to have something done.
Diposting oleh
Hafiz
di
Thursday, January 17, 2008
0
komentar
Label: effectivity
Tuesday, January 15, 2008
Books are Simplified Version of Reality
Reading books is reading filtered and structured knowledge. Compare to other sources like news, articles, forums, it has relatively the highest signal to noise ratio. That value comes with a cost, most notably generalization and omission of some details and context-related materials. Relative to other more "real-time" sources it is more "sterile".
This is why when we read books we feel we got so much information but sometime we are left hanging when trying to implement it in our situation. It's because the details in books are already smoothen out, some parts are simplified, so it is up to the reader to put them back on the reality ground. If I am going to write about some new techniques I would not have enough space to cover all possible cases but only take that I think would be enough to inspire and make a point to the reader.
There's nothing wrong with it, of course. It's just how the books are positioned and made. It's the forums, mailing lists, discussion group and our own experience role to fill in the blank. Besides, it's where the fun lies anyway.
Diposting oleh
Hafiz
di
Tuesday, January 15, 2008
0
komentar
Label: miscellaneous