Tips for coding using hostile tools? [closed] - coding-style

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I am developing an application using the wrong tools. I don't wish to get into the rights or wrongs of this - the platform has been blessed as Strategic and nothing is going to change that now. But I'm hoping somebody can give me some tips on how to make the best of the situation.
We use a server-side language, let's call it X, and client-side HTML/JS/CSS (on IE6). X is primitive from an application development point of view (but excellent for data processing, which is why we are using it); it doesn't even have the concept of user-defined functions, so trying to make the application modular in any way is a challenge. Think tens of thousands of lines of nested if/then/else statements.
My current assumption is that reducing the spaghetti-factor of the code will not be possible, and that really great documentation is my only weapon against this becoming a totally unsupportable nightmare that ends up on TheDailyWTF.
Anybody got any other ideas?
(I don't mention what language X is simply because I'm hoping for answers to the general problem of working with deficient tools, not any particular tactics for X.)
Edit:
Ok, for the morbidly curious, X is SAS. I didn't want the question to focus on whether function-style macros are functions (they are not, and cannot implement design patterns), or to blame it - given the constraints of this particular project, I actually agree with the decision to use it! I am also sure that the majority of software is developed in incredibly non-optimal environments (broken tools, bad management, overbearing legacy burden, etc.), and that there must be strategies for making things work even so.

Are you familiar with Church thesis?
If you can't solve "A" in Y but you can emulate Z in Y and Z can solve "A" then by definition Y can solve "A".
Maybe you can write some generalized routine that somehow makes X more effective for the problem at hand? A sort of extension to X, or, even better, a little-language implemented in X?
It seems that others tend to conflate "little language" with documentation. While you can try to go that way (in this case I suggest you have a look at Robodoc) I was thinking something closer to Wasabi, in approach - i.e. really using your tool X to create a sort of interpreter for X++ or even Y, without knowing what X is I can't be, of course, more specific than that.

Does X have comments?
Write your little language aka pseudo code in the comments.

In addition to documentation, choices of variable names and conventions for how they are used may help a bit. Also you may be able to set up some structural conventions in the code so that there is some regularity. Way back when, when folks wrote assembler good coders produced readable code.

hmmmm, sounds like another MUMPS/Intersystems Cache developer ;)
Seriously though, you might want to check if there are any tools for 'X' which could map the flow of the program, or as part of the documentation process break out something like Visio or another similar tool where you can walk through the code and map out what it does (more or less). Hardest part would probably be having to go back and stare at that wall of code and jump right back in so anything you can do to document it/graph it/chart it will help.

Is it possible to use a different technology, better suited to your problem between X and the client-side?
Alternatively, you could use more IF/Then/else statements to construct modular blocks of code, which might help with maintenance.

I find it hard to believe that you don't have any form of user defined functions available in X - even batch files have functions (kind of)
As soon as you have functions, you can make things at least fairly modular.

You could find a language you like, and implement the usual "slap some data into a template"-level web-app stuff in that, and implement wrappers to call out to 'X' for the things it is good at.

Related

Do you think VS and Intellisense make us dumber? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I read this article, the parts of "Intellisense" and "Generated Code":
http://www.charlespetzold.com/etc/DoesVisualStudioRotTheMind.html
Do you think the Author's is right?
I don't agree that Intellisense is soooo bad for programmers. VS for C# uses to "hide" the controls' events in another file, but you can find them if you know enough about the language and you can modify them by hand. And with VS I don't need to memorize all the .Net classes I use.
I think it doesn't matter if you use an IDE or notepad but, if thsese RAD tools exist and are free... Why not to use them?
No I very much disagree with this point.
Yes, I do agree that intellisense allows me to keep less of an objects growing number of members in my head. I am dumber in the sense that I often know less about the intricate details of projects where I use intellisense heavily.
For instance, I can probably rattle off all of the members of the C++ types I use with great accuracy. I tend to be a VIM only guy for my C++ projects and hence don't really use intellisnsee. In C# and VB.Net projects though I couldn't rattle off the members with the same accuracy as I rely on intellisense more often.
But there is a trade off. Keeping all of the members in my head comes with a cost. When writing code, instead of focusing on the algorithm, I focus on the members. I have to constantly think about the naming convention of a particular type, or the parameter list, what's byref or by val, when writing out an algorithm in C++. In C#/VB.Net I'm more free to think about the algorithm as the IDE takes care of finding the members for me.
Does this mean I'm dumber? No it simply means I'm able to focus on the problem I'm actually trying to solve. I feel this makes me more productive and hence smarter not dumber.
It doesn't make smart people dumber, but it makes dumb people look smarter
No, modern programming tools and languages help the programmer focus less on the little things and more on the big picture.
The main goal is to design solid software. If a programmer doesn't have to worry about memorizing every method of a class, they can spend more time on engineering the product.
Our physics prof always said why memorize something you can look up. He always listed the required formulas on the board during exams. Seems to be intellisense is the same idea. Rather than remembering if the object uses a Count or a Length property, let VS tell me.
No, it enables us to code faster I think. Anything to make the coding process faster, easier and simpler is a step in the right direction in my opinion.
Not dumber, it makes us faster :)
I use intellisense and generated code to speed up development, not because I don't know what I'm doing. Therefore, I can't agree that using them makes you dumber.
I am the kind of person that will try to learn as much about a language as possible before attempting to use the tools that facilitate development in that language. In that regard, I have to agree with Matthew Jones' comment that "tools do not make people dumber...laziness and lack of drive do."
Programming is just moving forward to make life easier for the programmer and making him more productive.
It would be like complaining that we don't write assembly code anymore... it's important to know the big concepts and ideas behind it, but working with it would be weird (in most cases).
I don't think so.
Intellisense makes things like case sensitive spelling easier.
Is it MyArray.Count() or MyArray.Size() or Length(MyArray) ... ? Which return type is a particular method, again? Intellisense saves me a few minutes every day on Google for things like this.
Detail memmorization is not the most important skill in software development. It is better to have problem solving skills and the ability to find the information you need. If you invest more time in the details you will be lost when the next greatest language is born, but algorithms and patterns will still be relevant.
The question is of course....does Intellisense make programming less of a skilled profession?
Yes, I agree with the author. Intellisense (and many other Visual Studio features) is indeed "making us dumber" for the reasons mentioned in the article.
That's not always a bad thing. Sometimes it's more desirable to be productive than it is to get smarter. The challenge is striking the right balance. :)
The only qualm with IntelliSense that the author seems to have is the autocomplete when you press the space bar, which apparently he doesn't realize you can turn off in the Options menu.
Although, he claims that coding "has become a constant dialog with IntelliSense"... which makes no sense because you still have to pick the correct methods from the list! Without it, you'd simply have to search online for the name of the method instead of an instantaneous search.
It's interesting how the author ignores that IntelliSense can't tell you whether to use a StringBuilder or a String, etc.
Not at all. When the intellisense list pops up, does a programmer search through the whole list every time to find the function they were looking for? Maybe at first, but normally you keep typing until intellisense narrows down the list to the point where it's faster to use the up/down arrows and tab to complete.
Without intellisense, it would take a little longer to code given that you are experienced with the classes that you're using and a lot longer given that you aren't. It only serves as a speed tool and quick documentation of everything that's available.
It doesn't make us dumber; it is a necessity.
Back in the day (MS BASIC for me), there was no need for intellisense. The scope of the language was limited enough for a programmer to remember all keywords and functions.
Jump to today, intellisense is an absolute requirement. Take .Net for example. There is simply no way to remember or discover the many thousands of types, properties and methods. Oh sure, for a very small project you may know a bunch (100s?) of items. But let's be honest - there is no way a modern working programmer could exist without it.
Adding my two cents here.
From my own experience and as mentioned in the TFA I would say that the only drawback I've encountered so far is when you learn the language you might pick up bad habits. Using ArrayLists instead of List only because you're not aware of changing use clauses enables might give you some other datatype.
The author complains over that he gets the wrong datatypes when entering certain datatypes. While some of you will probably get a license, a weapon and start the man hunt, I've found that using naming conventions is an excellent way of forcing the intellisense to be working my way, especially when working in GUI-Control intensive forms & stuff.
No more so than calculators made for poorer mathematicians and physicists. Sure, using a slide rule forces you to keep a mental model of the order of magnitude of things, but it is really just a tool ... and better tools let you do better work.
This can be abstracted into the traditional question:
Does knowing more about the details help or hurt?
As a rule, experienced engineers and craftsman say, help. But knowing the details also lets you know when the details don't matter, which is what Visual Studio/Intellisense provides. (I'm sure there's a pithy proverb that could be said here, but I don't feel up to thinking up a quip).
Dumb & Lazy.
Interesting question. Sure I find Intellisense in some sense makes the job easier, but it's kind of like money. The more you have, the more you spend, not necessarily on things you need. I learned to program around '62, and somehow I got along without Intellisense for a really long time. What Intellisense does for me now is help me remember lots of classes and members that as little as 4 years ago I never knew I needed.
There's one tendency I've seen in software that never fails. Nature abhors a vacuum. Machines get bigger, so guess what, software gets bigger (but not always better). Machines get faster, so software gets slower. Now people can get help typing long names, so the code gets really verbose. Now people get help remembering lots of classes, so guess what, there are lots more classes to remember. This goes a long way to helping the software get bigger and slower.
I do a lot of performance tuning, and what is the dominant cause of slowdown? It is galloping generality caused by overdesign with too much data structure, too many classes, and too many layers of abstraction. In a word, "bloat". Here is just a small example.
I find Visual Studio's tools conducive towards more experimentation. When you're dealing with the Win32 API in C (for example) you can't really poke around too easily. When you're working with C#, it's a snap to have a little explore around a library and learn what it does without breaking out MSDN or a disassembler for the entire evening.
If you're a naturally curious programmer, Intellisense won't change that. If you're not, Intellisense won't change that either. To paraphrase one of my colleagues "I think it's a waste of time looking through huge books when you can just take an implementation from the web and move on to the next thing".
It's an old argument anyway, pre-Intellisense. Does BASIC rot the mind where writing in x86 doesn't? Is knowing an algorithm inside out relevant when every single programming language you're going to use in your role has a tried and tested library?
I find that those who consider programming a hobby or a skill are inclined to comprehend and investigate. Those who consider it the day job don't. Regardless of any frippery around it, it's more about a programmer's mindset than what is made available.

Throwing out your first draft of work - is there a compatible methodology? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Are there any programming methodologies that take into account the concept that the first round of written code is likely to be not what you want to use? The most common thing I hear at the end of a project from a developer is 'If I could do that again, I'd do it so differently.' This is almost an exact mirror of the process a writer goes through after writing a first draft. The difference seems to be that writers then rewrite and rewrite again until they're ready to move into the editing stage, whereas developers seem to write and then refine their first draft with testing and refactoring.
I'm certainly no fan of trying to use alternative analogies to define the development process, but I do think there's value in recognising that your first draft is just to get ideas down, you need further rewrites in order to produce something worthwhile. I just don't think I've ever encountered a programming process or project methodology that recognises that, so I was hoping that the vast collective concious of Stackoverflow might have an idea of where I might start exploring this possibility?
Prototyping seems to address the problem in some way. The wikipedia article on Prototyping names an approach called 'Throwaway prototyping' which seems inline with your way of thinking.
What you are describing is called throwaway prototyping. The idea is that as soon as you have your preliminary requirements, you create a basic model of the system to show the user and/or customer what the final system might look like and how it might function (although there's no real functionality). The user provides feedback on this prototype.
If you wanted to utilize throwaway prototyping, my first suggestion would be to start looking at the spiral process model. However, I'm not familiar with very many methodologies that explicitly utilize throwaway prototyping. The more "agile" methodologies favor evolutionary prototyping or incremental prototyping. The only time I've ever personally used throwaway prototyping was to only prototype the user interface, as the underlying system was already under development and I used whiteboards and pen and paper for the prototypes.
Besides, this is one of Brooks's ideas which he himself found not the most effective after some revision: you've probably heard of "throwing away two systems after planning to throw away just one". Fortunately many such troubles can be overcome nowadays thanks to agile methodologies.
This is exactly the argument that Bruce Eckel is making here.
I would argue that the best thing to do is modularize very well. For example, if you're writing a kernel, the "Get the next available free memory frame" function should reside in its own function. That way, when you figure out that it's written in a really crappy way, you simple erase (of course you're using version control) and start from scratch. That way, your existing modules exist as a way to test your new code.
Going from start to finish and then start to finish again is an awesome way of going through a large percentage of the same bugs again.

The "Should be easy for a junior developer to understand" argument [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Does anyone actually think this is a good reason to "Dumb down" your code?
When a manager asks you to make your code simple (in terms of technology skills required to understand it) at the cost of more verbose cluttered code what should you do?
I highly disagree. Junior developers will end up being Senior developers. How? By encountering advanced topics that aren't taught in school.
My code base now makes heavy use of Inversion of Control containers. I would never revert my code to the old way because a junior developer had issues groking IoC. Instead I would take them out for a beer after work and discuss it. The more the junior dev learns the less hand holding needs to be done.
Here's a blog post discussing this very topic.
If you're constantly dumbing down your code or designs, it's a pretty good way to make sure your junior developers stay dumb. Challenge them and use it as a mentoring opportunity. Of course, some will never learn, but you've got bigger problems at that point.
It's not just pointy-haired bosses either. As a senior dev, it's often difficult to resist the urge to mommy junior developers. "Oh I'll just do this part because it's way too hard for them", or it'll take them too long, or they'll get way off in the weeds.
And finally, make sure you strike a balance between idiomatic code that uses the full power of a language vs idiomatic code that abuses that power. There's no reason you need to override the || operator just to run its args in two separate threads. At least dumb the code down a little for your older, dumber, future self.
Well, I think it's reasonable to avoid using "clever" language constructs unless they really, really make the code better - at which point if a junior developer sees it, hopefully they'd ask rather than just being flumoxed.
Here's an alternative way of phrasing it though: "Write your code so that it's easy enough to understand that if you get called at 3am and asked to fix a bug in it, you can still understand it."
Seriously, make it as easy to understand as possible. That doesn't mean a comment every other line - it means a comment where the purpose of a piece of code isn't obvious, and only then where the preferred choice of "well make it obvious then" doesn't work.
There's a difference between puzzle code and complex code.
I've found that the single biggest issue is that there is a big difference between "easy to understand by reading" versus "well-factored", and that the two goals are often in direct tension with one another. In well-factored code, there is a lot more jumping around between classes and a lot of virtual dispatch, so the path through the code is very non-linear.
Yes readability and being able to easily understand code is a big part of maintainability in my opinion.
Well if you intend to maintain your code forever, never change jobs, never feel the urge to work on something new, and can assure everyone you will never be hit by a truck, then sure there is no need to dumb down that puzzle code.
No. In the past, I've learned a lot from seeing the tricks of more experienced developers. I'd much rather have had the opportunity to learn something new from them than have had them dumb things down for me.
Its a balancing act...
If any 3 people on your team can 'read' your code and know what its doing... no need to change. However if you're the only person who can understand your code (no matter how rad/clever you think it is).. maybe you should take it down a few notches.
Another guideline to help would be to 'Try the simplest thing that works.' All the latest buzz words are nice to know however what it is even more important is having the skill to spot where you could get by without using them. You don't need to spray paint your code with IOC or Frameworks or Design Patterns...
The manager's side of this argument is sorely missed in this thread :) (and for the record.. I'm not one). His/Her major concern being he doesn't want a dark area of code that no one else dares to venture into.. so if you can convince your boss that a few other people on the team can make an arbitrary fix (or better yet.. show an actual bug fixed by someone else) - the mgr should let you off the hook. Disagreeing with your boss is another art :).. but you can talk things out usually.
You dont have to go all the way backward to Lowest Common Denominator.. strike a balance.
Your goal should not be for your code to be easy to understand for a junior developer. Instead, it should be easy to understand for a maintainence programmer.
This means:
Local "complexity" is okay, when needed. If they see the complex code they'll know they need to dig deeper.
Hidden complexity is bad. If you can't see that changing a piece of code will have subtle side effects then maintaining the code will be a nightmare.
New technologies that are visible are also okay, when not taken to extremes.
This is because those that maintain code rarely have the same overall understanding of the system. Or the time to develop it.
I disagree with the manager: What needs to be simple is the code, not the technology used to write it.
I would, however, impose a closely related requirement:
The internal documentation states clearly what technologies are needed to understand this code, and it gives references to places where those technologies can be learned.
For example, even as a senior developer, I find all matrix codes baffling. But if somebody gives me a reference to the right part of Numerical Recipes, I can puzzle out the details.
Yes. It's a very valid reason to take it down a notch. The reality is that a very, very large number of developers (as in most) are at the junior level.
As far as what you should do... Say "Yes Sir" or "Yes Ma'am" and do it. There is only one boss in that relationship.
UPDATE:
As some people seem to think that having a jr dev learning advanced topics while wading through obfuscated code I want to throw one more thing in here.
When ANY developer (jr or otherwise) runs into code they don’t understand, their first approach is to refactor it into something that is understandable. This is called the “Wow that code is crap I must rewrite it!” syndrome. I’m willing to bet everyone on this board has experienced it. So, as a business owner, do I want to pay for code to be developed each time a new person comes by or do I want to pay for new features to be added?
Guess which person I’m going to keep around longer.
If you dumb down your code, you're going to be stuck working with dummy junior programmers who will never be familiar with advanced coding techniques. If there's any verbose code that's trying to express an inherently complex procedure that you wrote, the aforementioned junior developer probably wouldn't be able to see the forest for the trees anyways. And they'd probably screw up if they had to express a complex concept if all they knew were basic primitive constructs whereas if they knew how to express what they meant tersely and elegantly, the code has a better chance of being correct.
Scott Muc said:
"I've found that the single biggest issue is that there is a big difference between "easy to understand by reading" versus "well-factored", and that the two goals are often in direct tension with one another. In well-factored code, there is a lot more jumping around between classes and a lot of virtual dispatch, so the path through the code is very non-linear."
Quoted for truth, and I think this is one of the biggest problems with C++ code in general. If you're the one that wrote the code, it's pretty easy to come up with a very complicated set of stuff that is well factored, makes lots of sense if you already know it, works well, and generally resembles a diamond crystal, etc. but which, from the perspective of someone who's trying to figure out how you got there and why things are the way they are and how things work, and how one might make changes that fit into the existing system and satisfy new requirements, is almost completely opaque and impenetrable.
How does this kind of situation help maintainability? That situation is one of my main beefs with C++ programmers. Far better to have a mess of plain C code which can be hacked upon than a diamond crystal of inpenetrably super-factored code which nearly nobody can figure out how to sensibly modify without smashing the crystalline structure.
One way to "dumb down" code that I actually think is an excellent practice is to use longer variable names and longer function names. Naming variables and functions to make their purpose easily understandable is a significant engineering task, IMHO, and takes extra effort on the part of the original author of the code. Damian Conway has some excellent examples in "Perl Best Practices". Some examples include: Prefer "final_total" to "sum"; prefer "previous_appointment" to "previous_elem", prefer "next_client" to "next_elem". Prefer "sales_records" to "data". Etc. He also pushes for using grammatical templates (Noun-adjective) and staying consistent. Don't use max_displacement one place and then use VelocityMax in another. Index variables need real names too:
sales_record[i] vs sales_record[cancelled_transaction_number]
I frequently "refactor" my code at the end of a development cycle by finding new names for all my functions and variables. In a modern editor it's trivial to change them all, and it's only at the end that I really figure out what I used them for. "Dumbing down" code this way isn't classic C, but it's easier for me when I come back months later asking WTF did I do?
It depends on the code. Is this something being shipped in your flagship product that requires use of the features your manager wants you to remove for performance reasons? If the answer is yes I would try to have your manager let you keep the code and just write up a document explaining in detail the section of code that is hard to understand. If it's an internal app that needs to be maintained by lots of different people and the complex features can be removed with out negatively affecting the program remove them and pick more important battles to fight.
You should just remind your boss that you can build rocket ships or chicken coops, and he will have to pay you the same for either one. Do what they say but generally an environment like that lends itself to people looking for a new environment.
The old quote is appropriate here:
Make everything as simple as possible,
but not simpler.
I've known developers who wrote highly obfuscated code that they felt was advanced but which the rest of the team felt was unreadable and unmaintainable. Part of this involved overuse of advanced language features (in C, the ternary operator and the comma operator) and writing in an obscure personal idiom (for example, replacing ptr->item with (*ptr).item everywhere) that no-one else would ever be able to maintain. The author was trying to outsmart the optimizer (which to be fair, was far from good).
Note: I'm not suggesting that "x = (p == NULL) ? "default" : p->value;" is complicated, but when someone uses ternary operators that span many lines, are nested, and make heavy use of the comma operator, code quickly becomes unreadable.
In this sort of case, "dumbing down" the code would have been a good idea. The problem was not advanced algorithms nor advanced language features, but overuse and inappropriate use of advanced language features, and an obscure personal idiom.
However, in the case you are asking about, where the manager's changes make the code more difficult to read and maintain, I agree with you and the others who have responded. I just wanted to point out the alternative that no-one else has mentioned.
I suggest keeping the code in a "Geeky-level" and comment it well so that the juniors can understand the intention behind the code and simultaneously learn a better way (or a right way) to code, so we have the best of both he worlds.
I think it is the manager's way of politely telling you that your code is too obfuscated/complex/jumbled/puzzle code...whatever you want to call it. Sometimes we get so involved writing our codes that we forget that someone else will have to come along and read it later.
I learned it the hard way and, in retrospect, find that it was the better way. Let the cycle repeat itself.
I agree 100% with the argument. With one major addition: Train your junior developers until they understand your code ;-)
I'm talking about using "unusual" technologies. In this case it's JQuery.
This issue came up when I was writing a wizard control for user registration.
The navigation menu needed to be customised and the current step in the wizard had to have a different css class in the menu. This meant I needed to get access to the currently selected step when generating the menu. My solution was to output the current step index in a hidden html field which could then be read by JQuery in order to customise the css.
I thought that this was much nicer and cleaner than using the databinding syntax in ASP.NET which doesn't have compile-time checking and messes up the layout of the html.
The databinding solutions is "standard" while the JQuery one is "unusual" which means that it's less likely to be understood by a junior.
I'm trying more and more these days to provide the required data for the UI rather than hack it into the UI with databinding which is why I added the hidden field with the current step index.
It is simply impossible to make progress or to innovate in any industry without doing things that others don't understand. Innovation is necessarily blasphemous. Why? Because if you're doing things that make sense to everyone else around you, the odds are you're not the first one doing it. ;)
That being said, there is a significant difference between doing something that is difficult to understand simply because it's a new or complicated problem versus doing something that's difficult to understand because you're trying to show off or you think confusing people will somehow gain you job security (which I've never seen work, but I've heard of people trying).
Should you make things easy to understand? Yes absolutely, as much as humanly possible. However a program that works and does its job well is the higher priority.
The manager's complaint should never be "don't do this because our junior guys don't understand it" -- it should only ever be "do x instead of y whenever feasible because x is easier to read / understand". This also assumes that x and y are equivalent (accept the same input and produce the same result).
I can't stand when managers do that... I've had three different managers bawl me out for using perfectly normal code the way it was designed to work, not because I was doing anything complicated, but rather only because they felt like it was too much effort for the other guys on our team to go RTFM on the language we were using. As a management strategy, that's totally backwards. It's like being the Holy Roman Catholic church and insisting that the laymen are too dumb to be trusted with literacy.
If you want to know really how ridiculous some of these managers get, try this: I had one manager bawl me out for declaring a variable as a type of "boolean" because he didn't feel the other programmers could handle it. Actually when I asked why, his answer was "because we don't do that here", which is a non-answer, but I interpreted it to mean "dumb it down". They were also berating me for that and similar practices as though it should be obvious that good programming habits were actually "bad" and that I should already know why even though they had never expressed a preferred programming style (either formally or informally). Needless to say, it was a bad job.
Make sure you can understand what it does 6 months down the road.
When in doubt, COMMENT your code. That's what comments are for.

How to write a linter? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
In my day job I, and others on my team write a lot of hardware models in Verilog-AMS, a language supported primarily by commercial vendors and a few opensource simulator projects.
One thing that would make supporting each others code more helpful would be a LINTER that would check our code for common problems and assist with enforcing a shared code formatting style.
I of course want to be able to add my own rules and, after I prove their utility to myself, promote them to the rest of the team..
I don't mind doing the work that has to be done, but of course also want to leverage the work of other existing projects.
Does having the allowed language syntax in a yacc or bison format give me a leg up?
or should I just suck each language statement into a perl string, and use pattern matching to find the things I don't like?
(most syntax and compilation errors are easily caught by the commercial tools.. but we have some of our own extentions.)
lex/flex and yacc/bison provide easy-to-use, well-understood lexer- and parser-generators, and I'd really recommend doing something like that as opposed to doing it procedurally in e.g. Perl. Regular expressions are powerful stuff for ripping apart strings with relatively-, but not totally-fixed structure. With any real programming language, the size of your state machine gets to be simply unmanageable with anything short of a Real Lexer/Parser (tm). Imagine dealing with all possible interleavings of keywords, identifiers, operators, extraneous parentheses, extraneous semicolons, and comments that are allowed in something like Verilog AMS, with regular expressions and procedural code alone.
There's no denying that there's a substantial learning curve there, but writing a grammar that you can use for flex and bison, and doing something useful on the syntax tree that comes out of bison, will be a much better use of your time than writing a ton of special-case string-processing code that's more naturally dealt with using a syntax-tree in the first place. Also, what you learn writing it this way will truly broaden your skillset in ways that writing a bunch of hacky Perl code just won't, so if you have the means, I highly recommend it ;-)
Also, if you're lazy, check out the Eclipse plugins that do syntax highlighting and basic refactoring for Verilog and VHDL. They're in an incredibly primitive state, last I checked, but they may have some of the code you're looking for, or at least a baseline piece of code to look at to better inform your approach in rolling your own.
I've written a couple verilog parsers and I would suggest PCCTS/ANTLR if your favorite programming language is C/C++/Java. There is a PCCTS/ANTLR Verilog grammar that you can start with. My favorite parser generator is Zebu which is based on Common Lisp.
Of course the big job is to specify all the linting rules. It makes sense to make some kind of language to specify the linting rules as well.
Don't underestimate the amount of work that goes into a linter. Parsing is the easy part because you have tools (bison, flex, ANTLR/PCCTS) to automate much of it.
But once you have a parse, then what? You must build a semantic tree for the design. Depending on how complicated your inputs are, you must elaborate the Verilog-AMS design (i.e. resolving parameters, unrolling generates, etc. If you use those features). And only then can you try to implement rules.
I'd seriously consider other possible solutions before writing a linter, unless the number of users and potential time savings thereby justify the development time.
In trying to find my answer, I found this on ANTLR - might be of use
If you use Java at all (and thus IDEA), the IDE's extensions for custom languages might be of use
yacc/bison definitely gives you a leg up, since good linting would require parsing the program. Regex (true regex, at least) might cover trivial cases, but it is easy to write code that the regexes don't match but are still bad style.
ANTLR looks to be an alternative path to the more common (OK I heard about them before) YACC/BISON approach, which it turns out also commonly use LEX/FLEX as a front end.
a Quick read of the FLEX man page kind of make me think It could be the framework for that regex type of idea..
Ok.. I'll let this stew a little longer, then see how quickly I can build a prototype parser in one or the other.
and a little bit longer

How do you prevent over complicated solutions or designs? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Many times we find ourselves working on a problem, only to figure out the solution being created is far more complex than the problem requires. Are there controls, best practices, techniques, etc that help you control over complication in your workplace?
Getting someone new to look at it.
In my experience, designing for an overly general case tends to breed too much complexity.
Engineering culture encourages designs that make fewer assumptions about the environment; this is usually a good thing, but some people take it too far. For example, it might be nice if your car design doesn't assume a specific gravitational pull, nobody is actually going to drive your car on the moon, and if they did, it wouldn't work, because there is no oxygen to make the fuel burn.
The difficult part is that the guy who is developed the "works-on-any-planet" design is often regarded as clever, so you may have to work harder to argue that his design is too clever.
Understanding trade-offs, so you can make the decision between good assumptions and bad assumptions, will go a long way into avoiding a needlessly complicated design.
If its too hard to test, your design is too complicated. That's the first metric I use.
Here are some ideas to get design more simpler:
read some programming books and articles, and then apply them in your work and write code
read lots of code (good and bad) written by other people (like Open Source projects) and learn to see what works and what does not
build safety nets (unit tests) to enable experimentations with your code
use version control to enable rollback, if those experimentations take wrong turn
TDD (test driven development) and BDD (behaviour driven development)
change your attitude, ask how you can make it so, that "it simply works" (convention over configuration could help there; or ask how Apple would do it)
practice (like jazz players -- jam with code, try Code Kata)
write same code multiple times, with different languages and after some time has passed
learn new languages with new concepts (if you use static language, learn dynamic one; if you use procedural language, learn functional one; ...) [one language per year is about right]
ask someone to review you code and actively ask how you can make your code simpler and more elegant (and then make it)
get years under your belt by doing above things (time helps active mind)
I create a design etc., and then I look at it and try and remove (agressively) everything that doesn't seem to be needed. If it turns out I need it later when I am polishing the design I add it back in. I do this over several iterations, refining as I go along.
Read "Working Effectively With Legacy Code" by Michael C. Feathers.
The point is, if you have code that works, and you need to change the design, nothing works better than making your code unit testable, and breaking your code into smaller pieces.
Using Test Driven Development and following Robert C. Martin's Three Rules of TDD:
You are not allowed to write any production code unless it is to make a failing unit test pass.
You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
In this way you are not likely to get much code that you don't need. You will always be focused on making one important thing work and won't ever get too far ahead of yourself in terms of complexity.
Test first may help here, but it is not suitable for all situation. And it's not a panacea anyway.
Start small is another great idea. Do you really need to stuff all 10 design patterns into this thing? Try first to do it "stupid way". Doesn't quite cut it? Okay, do it "slightly less stupid way". Etc.
Get it reviewed. As someone else wrote, two pairs of eyes are better. Even better are two brains. Your mate may just see a room for simplification, or a problematic area you thought was fine just because you spend many hours hacking it.
Use lean language. Languages such as Java, or sometimes C++ sometimes seem to encourage nasty, convoluted solutions. Simple things tend to span over multiple lines of code, and you just need to use 3 external libraries and a big framework to manage it all. Consider using Python, Ruby, etc. - if not for your project, then for some private use. It can change your mindset to favor simplicity, and to be assured that simplicity is possible.
Reduce the amount of data you're working with by serialising the task into a series of smaller tasks. Most people can only hold half a dozen (plus or minus) conditions in their head while coding, so make that the unit of implementation. Design for all the tasks you need to accomplish, but then ruthlessly hack the design so that you never have to play with more than half a dozen paths though the module.
This follows from Bendazo's post - simplify until it becomes easy.
It is inevitable once you have been a programmer that this will happen. If you seriously have unestimated the effort or hit a problem where your solution just doesn't work then stop coding and get talking to your project manager. I always like to take the solutions with me to the meeting, problem is A, you can do x which will take 3 days or we can try y which will take 6 days. Don't make the choice yourself.
Talk to other programmers every step of the way. The more eyes there are on the design, the more likely an overcomplicated aspect is revealed early, before it becomes too ossified in the codebase.
Constantly ask yourself how you will use whatever you are currently working on. If the answer is that you're not sure, stop to rethink what you're doing.
I've found it useful to jot down thoughts about how to potentially simplify something I'm currently working on. That way, once I actually have it working, it's easier to go back and refactor or redo as necessary instead of messing with something that's not even functional yet.
This is a delicate balancing act: on the one hand you don't want something that takes too long to design and implement, on the other hand you don't want a hack that isn't complicated enough to deal with next week's problem, or even worse requires rewriting to adapt.
A couple of techniques I find helpful:
If something seems more complex than you would like then never sit down to implement it as soon as you have finished thinking about it. Find something else to do for the rest of the day. Numerous times I end up thinking of a different solution to an early part of the problem that removes a lot of the complexity later on.
In a similar vein have someone else you can bounce ideas off. Make sure you can explain to them why the complexity is justified!
If you are adding complexity because you think it will be justified in the future then try to establish when in the future you will use it. If you can't (realistically) imagine needing the complexity for a year or three then it probably isn't justifiable to pay for it now.
I ask my customers why they need some feature. I try and get to the bottom of their request and identify the problem they are experiencing. This often lends itself to a simpler solution than I (or they) would think of.
Of course, if you know your clients' work habits and what problems they have to tackle, you can understand their problems much better from the get-go. And if you "know them" know them, then you understand their speech better. So, develop a close working relationship with your users. It's step zero of engineering.
Take time to name the concepts of the system well, and find names that are related, this makes the system more familiar. Don't be hesitant to rename concepts, the better the connection to the world you know, the better your brain can work with it.
Ask for opinions from people who get their kicks from clean, simple solutions.
Only implement concepts needed by the current project (a desire for future proofing or generic systems make your design bloated).

Resources