Python move from imperative to functional in production - python-3.x

I became infected with functional programming and reactive approach. For inspiration and ideas, I use Haskell and an awesome Rick Hickey article. In the python world I found for myself RxPy and funcy libraries. Now I have thousands of lines of imperative code, which I want to make functional. If everything is simplified, I have an interface of getters and setters for the database and a kernel that works like a state machine. Here's how it looks on pseudo code:
class State(object):
def __init__(id):
self.data = database_interface.get_state(id)
self.status = data['status']
def process(self):
if self.status == 'init':
self.handle_init()
elif self.status == 'request_data':
self.handle_request_data()
elif self.status == 'idle':
self.handle_idle()
# etc...
...
def on_new_message(msg):
id = msg['id']
state = State(id)
state.process()
I have a lot of if and for imperative business logic in my state handlers. And I'm really embarrassed how to move from the current model to reactive and functional. Here everything is very simplistic, but who already had a similar experience will understand me. I need advice on where to move next, from ideas to practice, larger than simple utilities or trivial REST api in a functional style. Also, I will be very helped by links to the source codes of really large projects, wherever I could get ideas. Thanks to everyone who responds, having a real experience porting the imperative code to the functional one. Yes, I understand that it will not be porting the code, but rewriting it from scratch. Again, I need examples of projects with a large number of business logic, where there is work with data and mutations of data. Anyway, thank you.

STOP. You have thousands of lines of code in production. It works. It may be a big ball of mud, but it works. I'm a big fan of FP, and write functionalish Python and very functional JavaScript for work myself, but that strikes me as backwards-thinking.
But if you can't resist the siren song of the shiny new thing, start one module at a time. Architecture such that you can't do that? That's a way bigger problem. Refactor to fix that first. Then go through the modules one at a time. If it can be made pure, make it pure. If you are having a hard time making modules pure, refactor them so that you that you have some impure modules and a bunch of pure ones instead of all mixed modules. Note that outwardly pure modules may use side-effects internally, as long as they don't leak beyond the module scope and the caller can't tell the difference that's fine. For now.
Now that you've done that you can change the internal implementation of those modules piecemeal without affecting the rest of the program. Try to replace custom classes with generic data structures where possible, especially at module boundaries. Note that doing so can have a negative impact on perf: profile!
Note that a lot of these tips overlap with what many would consider best practices for defining good object oriented architecture as well (program to interfaces, don't let implementation details leak, KISS, etc.). That is not a coincidence.
Here's another good talk for inspiration. Here's a link to clean architecture of Uncle Bob. Although geared towards UI programming its relevant.
DON'T go read/listen and say "I've got to implement the hexagonal ports-and-adapters pattern with a message queue for IPC or we're doomed!". Again, you have working code. Change it carefully, ideally a bit here and there, respecting what that means (especially to your users).
If all of this seems rather harsh, it's because I've been down this road, and trust me, it hurts. If you don't want to see your new-found enthusiasm vanish in a cloud of bug-reports then tread slowly and softly. I kinda like node.js but have shot myself in the foot by forever staining its reputation at my employer by doing the kind of thing you're talking about doing. Take heed, spare yourself some pain simply by slowing down.

Related

Why modeling/diagramming?

I'm thinking about general modeling (diagramming) standards and tools such as BPMN, UML, data modeling, etc.
Why do we need modeling?
Usually on what phase is modeling essential for you? communication? document and report?
How can you benefit from them in work or daily life?
Thank you!
You coined the most important word already: communication
Not only with others, but also with your future self. If you write an application now, and return to it after a few months pause, it will be hard to find your way around. Certainly, this depends on the size and complexity of the application in question. But having some visual representation will always be helpful.
Also, diagramming the application before actual development is a great way to wrap you head around everything. Normally, you will detect problems in you initial idea that are easy to fix at that stage. And as said, these diagrams will become helpful in the future.
Showing others how the application works internally is equally important. Everybody has a different way to approach problems. So something that is intuitive for you might seem weird in someone else's eyes. This makes it hard to grasp the concepts of an application someone else has written.
Also remember that only few of us (is any) write perfect code, and do a perfect architecture. We are human, we make errors.
Let's say for example that there is this nifty design pattern you heard of called "decorator", and you want to use it. Naturally, the word "decorator" will appear in your code, and people reading it will think: "Hey, I know this pattern. No need to read the gory details. I'll just handle it as a black-box and use it." But what if you misinterpreted the pattern and implemented it incorrectly. Now the person using it as a black-box will run into problems. These may range from small bugs to non-compiling API-calls. If you have a diagram of the whole thing, it will be much easier to pinpoint the cause.
The biggest problem with modelling is to keep the diagrams in-sync with your code. During the project life-time you will make changes. Small ones and big ones. In a perfect world, you would update the diagrams, think about it, let it sink into your brain, and then implement it. But the world's hardly perfect. So you may end up implementing something before diagramming it (if it's actually diagrammed at all). This whole process is cumbersome. Be it because the diagram software you use is crap or just simply because of time constraints.
Personally, I like to create an initial diagram. And once I'm happy with it, I dive into implementation. I won't revisit the diagram for small changes. Yes, after a while the code will deviate from the diagram, but the Big Picture is still there. If I need to make a bigger architectural change, I will revisit the diagram for sure.
What I will do however is keep the in-code documentation up-to-date. Most documentation extraction tools (like javadoc) give you the possibility to use markup which is useful to make the generated docs readable and usable. Especially when using hyperlinks.
So, coming back to one of your points, where you ask what the benefit is during the daily developer life, I think that the larger diagrams don't make that much of a difference there. Simply because once you grasped the concepts of the project, you will not need the diagram anymore as you peruse the codebase on a daily basis. What comes in handy though are proper code docstrings. Primarily because many IDEs display them while coding, or at least make it easy to jump to them. With diagrams, that's not so much the case.
Diagrams however are useful to get started quickly with a project.
One more thought about flow-charts/activity-diagrams: I find these mostly useless. except for complex algorithms, as it helps you visualize the cyclomatic complexity. But quite honestly, I have never needed to write a complex algorithm myself. I always found ready-to-use implementation in either the standard library or in a third-party library.
And one final note: This question should have been posted on https://softwareengineering.stackexchange.com/ ;)
I can only speak for flowcharts and diagrams for state machines, but the answer might apply also here: If you chart something, you are forced to think about your underlying stuctures. Usually bad structures tend to be more hard / ugly to draw as a diagram.

Resources for learning how to better read code

I recently inherited a large codebase and am having to read it. The thing is, I've usually been the dev starting a project. As a result, I don't have a lot of experience reading code.
My reaction to having to read a lot of code is, well, umm to rewrite it. But I need to bring myself up to speed quickly and build on top of an existing system.
Do other people have techniques they've learned to absorb a code base? At this point, I'm just reading through the code. I've tried generating UML diagrams using UModel. They're so big they won't print cleanly and when I zoom in, I really do lose the perspective of seeing all the relationships.
How have other people dealt with this problem?
Wow - I literally just finished listening to a podcast on reading code!!!
http://www.pluralsight-training.net/community/blogs/pluralcast/archive/2010/03/01/pluralcast-10-reading-code-with-alan-stevens.aspx?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+pluralcast+%28Pluralcast+by+Pluralsight%29
I would recommend listening to this. One interesting point that was made that I found radical and may be something you could try (I know I'm going to!). Download the entire source code base. Start editing and refactoring the code then...throw that version away!!! I think with all the demands that we have with deadlines that doing this would not even occur to most developers.
I am in a similar position to you in my own work and I have found the following has worked for me:
- Write test cases on existing code. To be able to write the test case you need to be able to understand the cde base.
- If it is available, look at the bug\issues that have been documented through the life cycle of the product and see how they were resolved.
- Try and refactor some of the code - you'll probably break it, but that's fine you can throw it away and start again. By decomposing the code into smaller problems you'll understand it bettter
You don't need to make drastic changes when refactoring though. When your reading the code and you understand something, rename the variable or the method names so the better reflect the problem the are trying to solve.
Oh and if you can, please get a copy of Working Effectively with Legacy Code by Michael C. Feathers - I think you'll find it invaluable in your situation.
Good luck!
This article provides a guideline
Visualization: a visual representation of the application's design.
Design Violations: an understanding of the health of the object
model.
Style Violations: an understanding of the state the code is currently
in.
Business Logic Review: the ability to test the existing source.
Performance Review: where are the bottlenecks in the source code?
Documentation: does the code have adequate documentation for people
to understand what they're working on?
In general I start at the entry point of the code (main function, plugin hook, etc) and work through the basic execution flow. If its a decent code base it should be broken up into decent size chunks, and you can then go through and figure out what each chunk of the code is responsible for. Looking back at when in the execution flow of the system its called.
For the package/module/class exploration I use whatever doxygen will generate once its been run over the sources. It generates some nice class relation diagrams, inheritance hierarchies and file dependencies graphs. The benefit of these is they are each focused on a single class and how it ties it with its neighbors, siblings and parents, so the graphs are usually of manageable size and easy to understand.
As you understand what different, classes, functions and sub-systems do I like to add comments to fill what sounds like obviously missing documentation. This helps you when you re-read through the code the second time.
I would recommend another podcast and resources:
SE-Radion episode on Software Archeology

What is a good example to show to a non-programmer to explain what programming "looks like"? [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 last month.
The community reviewed whether to reopen this question last month and left it closed:
Original close reason(s) were not resolved
Improve this question
A friend of mine asked me the other day if I'm just looking at lists of numbers when I'm programming, or how it works. I tried to explain that it's generally more like math formulae, with the odd english word tossed in, and that it's generally mostly readable. But that's a very vague explanation, and it doesn't really explain much to a non-programmer.
But it got me to thinking about what would make a good example. Not because I want to teach her programming or anything, but simply to give her an idea of what program code "looks like".
And that got me to wonder about what would actually work as a good example. And that's turning out to be surprisingly difficult.
My first thought was obviously a simple "Hello World" program. But it really doesn't show anything useful. It doesn't really show how we use functions, or variables, or control flow structures like if or while to make a program that actually does something. There's no logic to it. The program doesn't react to anything.
So perhaps something like computing prime numbers would be a better example. But then again, that might be too theoretical and impractical... (What good is that? What does it have to do with writing "real" programs?) And again, there's no significant control flow logic in it. It's just a straight sequence of maths.
And also, which language should be used?
Ideally, I don't think it has to be a very "clean" language. But rather, it should probably make the structure clear. If it does that, then a certain amount of noise and clutter might be fine. Perhaps something like C++ would actually be a better example than Python for that reason. The explicit curly braces and type specifiers are obvious "hooks" to help explain how the program is structured, or to highlight that it's not just simple statements that can almost be read out as english.
But with C++ we also get into some downright weird syntax. Why is std::cout << x used to print out x? Why not a "normal" function call syntax? And printf isn't much better, with its arcane format string, and lack of extensibility (do I want to complicate the program by using char* for strings? Or do I use std::string and settle for calling the seemingly unnecessary s.c_str() to get a string that can be printed with printf?
Perhaps a higher level language would be better after all. But which one? And why?
I know there are plenty of similar questions here about which language/example program to use to teach programming. But I think the requirements here are different. When teaching programming, we want simplicity more than anything. We want to avoid anything that hasn't been taught yet. We want to make sure that the student can understand everything on the screen.
I'm not interested in simplicity per se. But rather in giving an "outsider" an idea of "what a program looks like". And programs aren't simple. But they do generally exhibit a certain structure and method to the madness. What language/program would best highlight that?
Edit
Thanks for all the suggestions so far. Some of you have had a somewhat different angle on it than I'd intended.
Perhaps an example is in order. I can't fly an airplane, but I've got a basic understanding of what the cockpit looks like, and what a pilot "does" while flying.
And I'm not a trained carpenter, but I know a saw or a hammer when I see one.
But when you see anything to do with programming in movies, for example, it's usually just screens filled with garbage (as in the green text in the Matrix). It doesn't look like something a normal human being can actually do. There's nothing recognizable in it. Someone who isn't a programmer simply thinks it's black magic.
I don't want to teach her to fly, or to program software.
But I'd like to give her a basic frame of reference. Just an idea of "ah, so that's what you're working with. So it's not just random symbols and numbers on the screen". Even just showing a simple if-statement would be a revelation compared to the Matrix-style random symbols and numbers.
Some of you have suggested explaining an algorithm, or using pseudocode, but that's what I want to avoid. I'd like something that simply shows what actual code looks like, in the same way that you don't have to be a carpenter to look at a saw and get a basic idea of what it is and how it works.
When I was a kid, we once went on vacation in Italy. On the way down, the pilot let me into the cockpit of the plane. Of course, I didn't learn how to fly the plane. But I did get a peek into the pilot's world. I got an idea of how they make the plane go, what the pilot actually does.
That's really all I want to do. My friend has no interest in learning programming, and I don't want to force her to understand source code. But she was curious about what kind of tools or entities I work with. Is it Matrix-style symbols scrolling across the screen? Pure mathematics? English in prose form?
All I'm interested in conveying is that very high-level understanding of "What does it look like when I work".
BASIC
10 PRINT "Sara is the best"
20 GOTO 10
Update: when I was 12, my cousin (he was 14) brought Turbo Pascal 7.0 and installed it in my computer.
He programmed a tic tac toe game from scratch (in BGI mode, for those who know).
I watched/observed step by step how a program evolves until it becomes a complete application.
Until then, I knew only how to print strings in BASIC :-B
You can do a similar thing. Pair programming. Well, actually your friend will be an observer but she'll get an idea ;)
Why not consider a language that doesn't exist (or does, if you so believe) and use Pseudo Code? I think, depending upon what you want to achieve - I'd consider the example of task familiar to the person, but carved up into a pseudo code example.
I generally find the idea of "cooking" or "recipes" to be a great fit when explaining things to non-programmers.
I ask the person to imagine they had a recipe that was fairly complex - e.g. a curry & rice dish. I then suggest that they should try and write it down for someone who has absolutely no idea what they are doing, so that they can cook it.
There is a very definite few stages involved:
Gather the ingredients and tools for the job.
Prepare the ingredients. This is complex. e.g.
get 3 Small Red Peppers.
for each red pepper you have, chop it into chunks about 1cm square.
place the red pepper chunks into a bowl for later.
Seperately to this, call the prepare rice function and have this working asynchronously in the background while you continue on with the cooking.
I'm sure you can see where this is going... ;)
There are a lot of similarities with Cooking and Programming (as there are with many things, but more people have an understanding of cooking than of building a house).
There stages / similarities (as I see it) are:
Gathering: (declaration of what is required to achieve the goal and getting them together).
Preperation: Chopping the ingredients or readying the data connection objects etc for first use.
Asynchronous: The ability to have one thing going while another thing going.
Functions: The rice making, the chicken cooking and the curry cooking all require separate processes and only at the end can you have the makeCurry(chickenMeat, rice) function.
Testing: Ensure that as you are going along, you aren't missing any bits and that everything is going smoothly - e.g. ensuring chicken is cooked before you move to the next stage.
Garbage: Once you've done, you must ensure that you tidy up. ;)
Principals of Best Practice: There are efficient ways of doing things that like cooking, beginning programmers have to learn in addition to the code - sometimes it can be hard to get your head around. e.g. D.R.Y, how to chop efficiently with a knife & don't eat raw chicken ;)
Basically, I think for teaching programming as a general topic - I wouldn't necessarily teach from a language unless you had a compelling reason to do so. Instead, teach initially from the abstract until they understand at least the fundamentals of how things might fall together. Then they may find it easier when sat in front of a monitor and keyboard.
I think there may not be one "right answer" for this one. But I think maybe a few really good ideas you could maybe take bits from all of.
I would explain that programming is giving detailed instructions so the computer can make complex tasks.
How to make two cups of coffee?
Fill the kettle
Boil water
Coffee in cup
Pour on water
Add sugar
Add milk
Do 3 to 6 again
To answer your question directly - what programming “looks like”, I'd show them a print out of a large application. Toy apps or cute things like qsort in haskell really give the wrong idea.
It looks a bit like this. Sometimes.
Maybe everyone is concentrating too much on the code rather than tools. Possibly it's best to show her a project in an IDE, and how it includes various source files and maybe some diagrammatic things like a database schema or a visual user interface designer too. Visual Studio, Eclipse or Xcode are quite far away from most people's mental image of rapidly scrolling glowing green symbols on a black background.
I think you should download some big win32 application, written in AT&T assembly language, and show it to her in notepad, and tell her, "As you can see, it takes a superhuman like myself to program."
Code something that has any comprehensible value to a non-programmer. If I'd demonstrate Quicksort to my mother, it wouldn't be of any use.
Ask the person about his interests. If he/she's into stock exchange for example, hack together a script that reads some stock statistics from a appropriate web page and compiles them into an excel sheet (use csv, to avoid heavy brain-damage ^^) or maybe into a nice graph.
If the person uses Twitter, code something that counts the followers of his followers or something like that.
These tasks are simple enough to be done in a very short time and they already utilize a lot of the basic tools that we programmers use, like loops, libraries (for all the http stuff involved), maybe recursion.
After you're finished or while you're coding (even better), you can explain how your program does its magic.
Just keep it simple and talk in human language. If you show them megabytes of code and talk about things like prototypal inheritance, you just intimidate them and they will lose interest immediately.
To give my wife an idea of what I do to bring in a paycheck (It's real work! I promise! we don't just browse the web all day!) I sat down with her one evening with Python and showed her a couple of the basic concepts: calling a function (print), assigning and reading a variable, and how an if statement works. Since she's a teacher, I likened the concept of conditionals to working with preschoolers :)
IF you hit Jonny THEN you're in time out OTHERWISE you can have a snack.
After reviewing a couple of the very high level concepts, I then showed her the code to a simple number guessing game and let her play it while looking though the code.
# Guessing Game
import random
print("Guess a number between 1 and 100: ")
target = random.randint(1, 100)
guess = 0
guess_count = 1
while guess != target:
guess_count += 1
guess = int(input())
if guess == target:
print("Correct!")
if guess < target:
print("Higher...")
if guess > target:
print("Lower...")
print("Congratulations! You guessed the number in " + str(guess_count) + " guesses!")
Aside from the somewhat abstract concept of "import", this is a very straightforward example that is easy to follow and "connect" to what's happening on the screen, not to mention it actually does something interesting and interactive. I think my wife walked away from the experience a little less mystified by the whole concept without really needing to know much in the way of code.
I think the key is being able to have someone see the code AND it's end result side by side.
There was a CLI graphics package called LOGO, and best known for Turtle Graphics, used to draw shapes on screen using commands like LT 90, RT 105 etc. See if you can find that, it would be a nice experience to try and draw something of medium complexity.
LOGO - Logic Oriented Graphic Oriented programming language.
REPEAT 360 [FD 1 RT 1] -- draws a circle, etc.
See more at logothings or Wikipedia which also has links to modern logo interpreters.
The computer programmer writes programs.
While not programming, the computer programmer annoys attractive women in his workplace.
Then:
(source: markharrison.net)
Now:
When my 5 y.o. daughter asked me the question I made her "develop" the program for a little arrow "robot" that will get him into the upper-left-corner of the board using flowchart-like pieces of paper signifying moves, turns and conditions. I think it applies to grown-ups as well.
I do not claim the invention of this answer, though.
About your edit: I'm afraid, programmers have even less idea of the idea others have about programming. ;-) People think that programming is a matrix-like green video card corruption about as much as they think that spies are all equipped with James Bond's hi tech toys. And any professional in any field is normally irritated when watching the movie concerning his job. Because the movie maker has no idea! Do we know how to properly depict programming in the movie on the other hand? ;-)
I've found that the best approach to "teach someone what programming is without teaching them programming" is actually to just drop anything related to a specific programming language.
Instead (assuming they're actually interested), I would talk them through implementing a function in a program, like a simple bank loan application (most people have had to deal with loans at some stage, if they're above a certain age), and then poking holes in all the assumptions.
Like, what should happen if the user types in a negative loan amount? What if the user cannot afford the loan? How would the loan application know that? How would the loan application know which bank account to check and which payment history to check (ie. who is the user actually)? What if the user tries to type in his name in the loan amount field? What if the user tries to take the loan over 75 years? Should we limit the choices to a list of available lengths?
And then in the end: Programming is taking all of those rules, and writing them in a language that the computer understands, so that it follows those rules to the letter. At this point, if it is felt necessary, I would pull out some simple code so that the overall language can be looked at, and then perhaps written out one of the rules in that language.
Bonus points if you can get your friend to then react with: But what if we forgot something? Well, then we have bugs, and now you know why no software program is bugfree too :)
Definitively something either with graphics, or windows, in a higher level language.
Why? A non-programmer is usually a non-matematician too, that's why he won't get the beauty of sorting. However showing something drawn on a screen ("look, a window!", "look, so little typing and we have a 3D box rotating!") can work wonders ;).
What does it look like when you work?
It looks like typing.
Seriously though, programming is kind of like if Legos were text, and to build a big Lego house, you had to type a lot of text in, just right, hooking up the right pegs with the right holes. So that is how I generally describe it.
It's really hard to understand what programming is like just from a source code example, because it is so abstract.
There is nothing wrong with starting on hello world, as long as you can show what the computer actually does with it. You can then introduce one construct at a time. That's what programming is like- Making incremental changes, and seeing the results.
So you have a hello world program. Now change it to
string Name = getLine();
printf("Hello, %s", name);
then the if construct
printf("Do you like cake?");
string answer = getLine();
if(answer == "yes") {
printf("Yeay! I like cake too!");
} else if(answer == "no") {
printf("Filthy cake hating pig!");
}
then demonstrate that the last program fails when it recieves an answer other than either "yes" or "no", and how you would go about fixing it....
and so on. I don't think you need to go into deep concepts like recursion, or even functions really.
It doesn't really matter what programming you use for this, as long as you're able to show, on a computer, the result of these different programs. (though these psuedocode examples are probably pretty close to being valid python)
Robotics is great for explaining programming, I think, because even simple, contrived examples are practical. The robotics equivalent of Hello World or printing a list of numbers might be having the robot move in a line or spin in a circle. It's easy for a non-programmer to understand that for a robot to do ANYTHING useful it must first move and position itself. This lets you explain simple program structure and flow control.
You want the robot to move forward, but only while there is nothing blocking its path. Then you want it to turn and move again. That's a simple routine using basic flow control, and the functions that you're calling are pretty easy to understand (if your platform has decent abstractions anyway).
Graphics might also work. Anything that has immediate results. jQuery even, because everyone is familiar with rotating pictures and web animations. Even contrived examples like pushing elements around in the DOM has an easy to see effect, and most people will understand what and why the statements in the program do.
Things like Robocode and LOGO are probably really good for this.
(source: wikimedia.org)
{
wait for 6/8;
play F (5), sustain it for 1/4 and a half;
play E flat (5), sustain it for 1/8;
play D flat (5), sustain it for 1/8 and a half;
play F (4), sustain it for 1/16;
// ...
}
Perhaps a metaphor could be that of a composer writing a musical score. The job of a composer is the intellectual activity of creating music. With a score, the composer is telling the pianist what to play, and he does it by means of precise instructions (notes, pauses and so on). If the "instructions" are not precise enough, the pianist will play something different.
The job of a software developer is the intellectual activity of solving problems (problems that have to do with automated processing of data). With source code, the developer is telling the computer what to do, and he does it by means of precise instructions. If the instructions are not precise enough, the computer will do something different and will not solve the problem correctly.
I would just write something in pseudocode that demonstrates how to use a computer to solve an everyday problem. Perhaps determining which store is cheaper to buy a particular grocery list from or some such.
Why not just show the timelapse video A Day in the Life of a Scrum Team?
A programmer writes instructions for the computer to perform.
Running the program results in the computer actually following those instructions.
An example is a cook will follow a recipe in order to bake a loaf of bread. (even if it's in their head)... that's programming. Unlike my wife, the computer follows the recipe exactly every time. My wife, does it in her head and it turns out different but delicious every time ;-)
If you want to go ahead and teach this in more detail then pseudo-code is easy to understand.
e.g.
IF today's date is the 1st of may then
print to screen "Happy Birthday"
ELSE
print to screen "It's not your birthday yet"
The beauty of psuedo code is nearly anyone can understand it and this is the point of it.
Want to show her what programming looks like? Just pop a terminal and
find /
Surprised this is still open, and surprised no one has already given this answer. (I think. I might have accidentally skipped one of the 40 questions that no one is going to read anyway.)
Your answer is in your question
When I was a kid, we once went on vacation in Italy. On the way down,
the pilot let me into the cockpit of the plane. Of course, I didn't
learn how to fly the plane. But I did get a peek into the pilot's
world. I got an idea of how they make the plane go, what the pilot
actually does.
That's really all I want to do.
That's all you have to do. Pick a short exercise out of a tutorial. A moderately longer GUI one could also be beneficial due to the added visuals. (Games might be pushing the length a bit.) And let her watch you code. That's it. It's the same as your pilot example.
Also there are a number of online REPLs that will make watching you code even more immediate.
I say show him bubble sort.
It's an easy, understandable trick, converted to a formal language.
That's what our job is about. Expressing our ideas in a strict, formal language, such that even a machine can understand. A little similar to designing procedures for organizational design.
Code up something quick that reads stock quotes and writes them to an excel spreadsheet. This is easy enough to do with a few minutes and impresses non technical types very quickly as they see the practical value of it.
My usual choice is to retrieve a set of customer records from a database. Using C# and LINQ in Visual Studio, it takes maybe 10 minutes at most to build a web page and dump out the "Northwind" database customers into a grid. The nice thing is that a "list of customers" is something that almost anybody can understand.
Totally depends on the level of her interest (or your level of interest in her). Most people ask that question as idle conversation, and don't really want to know.
Programming is more than algorithms (like "How to make a cup of coffee), it's also fundamentally rooted in mathematics. Most people will be quickly tripped up by the subtle use of mathematical terms (what's a "function"?).
In order to really teach programming, it may help to think back to your own first programming experiences, your first programming teacher, your first programming language. How did you learn? when you were learning, what skills did you already have fresh in your mind (i.e., calculus)? What motivated you to want to understand what a variable is or why there are three different kinds of loops?
Language-wise: Use something like python. Really high level, non-curly-bracket probably better.
Alice which was developed at Carnegie Mellon.
Alice is an innovative 3D programming environment that makes it easy to create an animation for telling a story, playing an interactive game, or a video to share on the web. Alice is a teaching tool for introductory computing. It uses 3D graphics and a drag-and-drop interface to facilitate a more engaging, less frustrating first programming experience.
In pseudo-code:
function dealWithPerson(person){
if(ILike(person)){
getCookie().giveTo(person);
}
else{
person.tell("You shall receive no cookies!");
}
}
dealWithPerson(Person.fromName("Nick"));
dealWithPerson(Person.fromName("John"));
This demonstrates the concept of functions, object-orientation and strings, in a C-like syntax(when I say C-like syntax I refer to the weird characters).
It also shows how code can be reused.
Note that although it is pseudo-code, I wouldn't be surprised if there was some language that accepted this syntax(perhaps JavaScript allows this?).
You could also adapt this example to have loops.
Hope this helps show that person how a program looks like(since it is a realistic syntax and it is relatively easy to understand).
I have been teaching programming for many years and found out that the number of ways you need to explain things is equal to the number of students you have. But one method that works most of the time is as follows:
Present a flow chart that shown the flow of logic of a simple application
Write the instructions in full human language (e.g. English)
Abbreviate each instruction to the short-hand used in the programming language
Choose a less cryptic language like Basic or Pascal for teaching purposes
All code is simply shorthand for natural language. Written in full English most programs seem trivial.
As for a good algorithm, that is another story. It is sad to see many Computer Science courses no longer teach algorithms or brush over it.

Writing easily modified code

What are some ways in which I can write code that is easily modified?
The one I have learned from experience is that I almost always need to write one to throw away. That way I have developed a sense of the domain knowledge and program structure required before coding the actual application.
The general guidelines are offcourse
High cohesion, low coupling
Dont repeat yourself
Recognize design patterns and implement them
Dont recognize design patterns where they are not existing or necassary
Use a coding standard, stick to it
Comment everyting that should be commented, when in doubt : comment
Use unit tests
Write comments and tests before implementation, that way you know exactly what you want to do
And when it goes wrong : refactor, refactor, refactor. With good tests you can be sure nothing breaks
And oh yeah:
read this : http://www.pragprog.com/the-pragmatic-programmer
Everything (i think) above and more is in it
I think your emphasis on modifiability is more important than readability. It is not hard to make something easy to read, but the real test of how well it is understood comes when someone else (or you) has to modify it in repsonse to changing requirements.
What I try to do is assume that modifications will be necessary, and if it is not really clear how to do them, leave explicit directions in the code for how to do them.
I assume that I may have to do some educating of the reader of the code to get him or her to know how to modify the code properly. This requires energy on my part, and it requires energy on the part of the person reading the code.
So while I admire the idea of literate programming, that can be easily read and understood, sometimes it is more like math, where the only way to do it is for the reader to buckle down, pay close attention, re-read it a few times, and make sure they understand.
Readability helps a lot: If you do something non-obvious, or you are taking a shortcut, comment. Comments are places where you can go back and refactor if you have time later. Use sensible names for everything, makes it easier to understand what is going on.
Continuous revision will let you move from that first draft to a better one without throwing away (too much) work. Any time you rewrite from scratch you may lose lessons learned. As you code, use refactoring tools to eliminate code representing areas of exploration that are no longer needed, and to make obvious things that were obscure. The first one reduces the amount that you need to maintain; the second reduces the effort per square foot. (Sqft makes about as much sense as lines of code, really.)
Modularize appropriately and enforce encapsulation and separation of logic between your modules. You don't want too many dependencies on any one part of the code or that part becomes inherently harder to understand.
Considering using tried and true methods over cutting edge ones. You give up some functionality for predictability.
Finally, if this is code that people will be using before and after modification, you need(ed) to have an appropriate API insulating your code from theirs. Having a strong API lets you change things behind the scenes without needing to alert all your consumers. I think there's a decent article on Coding Horror about this.
Hang Your Code Out to D.R.Y.
I learned this early when assigned the task of changing the appearance of a web-interface. The code was in C, which I hated, and was compiled to a CGI executable. And, worse, it was built on a library that was abandoned—no updates, no support, and too many man-hours put into its use to change it. On top of the framework was a disorderly web of code, consisting of various form and element builders, custom string implementations, and various other arcane things (for a non-C programmer to commit suicide with).
For each change I made there were several, sometimes many, exceptions to the output HTML. Each one of these exceptions required a small change or improvement in the form builder, thanks to the language there's no inheritance and therefore only functions and structs, and instead of putting the hours in the team instead wrote these exceptions frequently.
In my inexperience I was forced to change the output of each exception, rather than consolidate the changes in an improved form builder. But, trawling through 15,000 lines of code for several hours after ineffective changes would induce code-burn, and a fogginess that took a night's sleep to cure.
Always run your code through the DRY-er.
The easiest way to modify a code is NOT to write code. Write pseudo code not just for algo but how your code should be structured if you are unsure.
Designing while writing code never works...for me :-)
Here is my current experience: I'm working (Java) with a kind of database schema that might often change (fields added/removed, data types modified). My strategy is to parse this schema and to generate the code with apache velocity. The BaseClass generated is never modified by the programmer. Else, a MyClass extends BaseClass is created and the logical components of this class (e.g. toString() ! )are implemented using the 'getters' and the 'setters' of the super class.

Have we given up on the idea of code reuse? [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 2 years ago.
Improve this question
A couple of years ago the media was rife with all sorts of articles on
how the idea of code reuse was a simple way to improve productivity
and code quality.
From the blogs and sites I check on a regular basis it seems as though
the idea of "code reuse" has gone out of fashion. Perhaps the 'code
reuse' advocates have all joined the SOA crowd instead? :-)
Interestingly enough, when you search for 'code reuse' in Google the
second result is titled:
"Internal Code Reuse Considered Dangerous"!
To me the idea of code reuse is just common sense, after all look at
the success of the apache commons project!
What I want to know is:
Do you or your company try and reuse code?
If so how and at what level, i.e. low level api, components or
shared business logic? How do you or your company reuse code?
Does it work?
Discuss?
I am fully aware that there are many open source libs available and that anyone who has used .NET or the Java has reused code in some form. That is common sense!
I was referring more to code reuse within an organizations rather than across a community via a shared lib etc.
I originally asked;
Do you or your company try and reuse code?
If so how and at what level, i.e. low level api, components or shared business logic? How do you or your company reuse code?
From where I sit I see very few example of companies trying to reuse code internally?
If you have a piece of code which could potentially be shared across a medium size organization how would you go about informing other members of the company that this lib/api/etc existed and could be of benefit?
The title of the article you are referring to is misleading, and is actually a very good read. Code reuse is very beneficial, but there are downsides with everything. Basically, if I remember correctly, the gist of the article is that you are sealing the code in a black box and not revisiting it, so as the original developers leave you lose the knowledge. While I see the point, I don't necessarily agree with it - at least not to a "sky is falling" regard.
We actually group code reuse into more than just reusable classes, we look at the entire enterprise. Things that are more like framework enhancement or address cross-cutting concerns are put into a development framework that all of our applications use (think things like pre- and post-validation, logging, etc.). We also have business logic that is applicable to more than one application, so those sort of things get moved to a BAL core that is accessible anywhere.
I think that the important thing is not to promote things for reuse if they are not going to really be reused. They should be well documented, so that new developers can have a resource to help them come up to speed, as well. Chances are, if the knowledge isn't shared, the code will eventually be reinvented somewhere else and will lead to duplication if you are not rigorous in documentation and knowledge sharing.
We reuse code - in fact, our developers specifically write code that can be reused in other projects. This has paid off quite nicely - we're able to start new projects quickly, and we iteratively harden our core libraries.
But one can't just write code and expect it to be re-used; code reuse requires communication among team members and other users so people know what code is available, and how to use it.
The following things are needed for code reuse to work effectively:
The code or library itself
Demand for the code across multiple projects or efforts
Communication of the code's features/capabilities
Instructions on how to use the code
A commitment to maintaining and improving the code over time
Code reuse is essential. I find that it also forces me to generalize as much as possible, also making code more adaptable to varying situations. Ideally, almost every lower level library you write should be able to adapt to a new set of requirements for a different application.
I think code reuse is being done through open source projects for the most part. Anything that can be reused or extended is being done via libraries. Java has an amazing number of open source libraries available for doing a large number of things. Compare that to C++, and how early on everything would have to be implemented from scratch using MFC or the Win32 API.
We reuse code.
On a small scale we try to avoid code duplication as much as posible. And we have a complete library with a lot of frequently used code.
Normally code is developed for one application. And if it is generic enough, it is promoted to the library. This works excelent.
The idea of code reuse is no longer a novel idea...hence the apparent lack of interest. But it is still very much a good idea. The entire .NET framework and the Java API are good examples of code reuse in action.
We have grown accustomed to developing OO libraries of code for our projects and reusing them in other projects. Its a part of the natural life cycle of an idea. It is hotly debated for a while and then everyone accepts and there is no reason for further discussion.
Of course we reuse code.
There are a near infinite amount of packages, libraries and shared objects available for all languages, with whole communities of developers behing them supporting and updating.
I think the lack of "media attention" is due to the fact that everyone is doing it, so it's no longer worth writing about. I don't hear as many people raising awareness of Object-Oriented Programming and Unit Testing as I used to either. Everyone is already aware of these concepts (whether they use them or not).
Level of media attention to an issue has little to do with its importance, whether we're talking software development or politics! It's important to avoid wasting development effort by reinventing (or re-maintaining!) the wheel, but this is so well-known by now that an editor probably isn't going to get excited by another article on the subject.
Rather than looking at the number of current articles and blog posts as a measure of importance (or urgency) look at the concepts and buzz-phrases that have become classics or entered the jargon (another form of reuse!) For example, Google for uses of the DRY acronym for good discussion on the many forms of redundancy that can be eliminated in software and development processes.
There's also a role for mature judgment regarding costs of reuse vs. where the benefits are achieved. Some writers advocate waiting to worry about reuse until a second or third use actually emerges, rather than spending effort to generalize bit of code the first time it is written.
My personal view, based on the practise in my company:
Do you or your company try and reuse code?
Obviously, if we have another piece of code that already fits our needs we will reuse it. We don't go out of our way to use square pegs in round holes though.
If so how and at what level, i.e. low level api, components or shared business logic? How do you or your company reuse code?
At every level. It is written into our coding standards that developers should always assume their code will be reused - even if in reality that is highly unlikely. See below
If your OO model is good, your API probably reflects your business domain, so reusable classes probably equates to reusable business logic without additional effort.
For actual reuse, one key point is knowing what code is already available. We resolve this by having everything documented in a central location. We just need a little discipline to ensure that the documentation is up-to-date and searchable in a meaningful way.
Does it work?
Yes, but not because of the potential or actual reuse! In reality, beyond a few core libraries and UI components, there isn't a large amount of reuse.
In my personal opinion, the real value is in making the code reusable. In doing so, aside from a hopefully cleaner API, the code will (a) be documented sufficiently for another developer to use it without trawling the source code, and (b) it will also be replaceable. These points are a great benefit to on-going software maintenance.
Do you or your company try and reuse code? If so how and at what
level, i.e. low level api, components or shared business logic? How do
you or your company reuse code?
I used to work in a codebase with uber code reuse, but it was difficult to maintain because the reused code was unstable. It was prone to design changes and deprecation in ways that cascaded to everything using it. Before that I worked in a codebase with no code reuse where the seniors actually encouraged copying and pasting as a way to reuse even application-specific code, so I got to see the two extremities and I have to say that one isn't necessarily much better than the other when taken to the extremes.
And I used to be an uber bottom-up kind of programmer. You ask me to build something specific and I end up building generalized tools. Then using those tools, I build more complex generalized tools, then start building DIP abstractions to express the design requirements for the lower-level tools, then I build even more complex tools and repeat, and at some point I start writing code that actually does what you want me to do. And as counter-productive as that sounded, I was pretty fast at it and could ship complex products in ways that really surprised people.
Problem was the maintenance over the months, years! After I built layers and layers of these generalized libraries and reused the hell out of them, each one wanted to serve a much greater purpose than what you asked me to do. Each layer wanted to solve the world's hunger needs. So each one was very ambitious: a math library that wants to be amazing and solve the world's hunger needs. Then something built on top of the math library like a geometry library that wants to be amazing and solve the world's hunger needs. You know something's wrong when you're trying to ship a product but your mind is mulling over how well your uber-generalized geometry library works for rendering and modeling when you're supposed to be working on animation because the animation code you're working on needs a few new geometry functions.
Balancing Everyone's Needs
I found in designing these uber-generalized libraries that I had to become obsessed with the needs of every single team member, and I had to learn how raytracing worked, how fluids dynamics worked, how the mesh engine worked, how inverse kinematics worked, how character animation worked, etc. etc. etc. I had to learn how to do pretty much everyone's job on the team because I was balancing all of their specific needs in the design of these uber generalized libraries I left behind while walking a tightrope balancing act of design compromises from all the code reuse (trying to make things better for Bob working on raytracing who is using one of the libraries but without hurting John too much who is working on physics who is also using it but without complicating the design of the library too much to make them both happy).
It got to a point where I was trying to parametrize bounding boxes with policy classes so that they could be stored either as center and half-size as one person wanted or min/max extents as someone else wanted, and the implementation was getting convoluted really fast trying to frantically keep up with everyone's needs.
Design By Committee
And because each layer was trying to serve such a wide range of needs (much wider than we actually needed), they found many reasons to require design changes, sometimes by committee-requested designs (which are usually kind of gross). And then those design changes would cascade upwards and affect all the higher-level code using it, and maintenance of such code started to become a real PITA.
I think you can potentially share more code in a like-minded team. Ours wasn't like-minded at all. These are not real names but I'd have Bill here who is a high-level GUI programmer and scripter who creates nice user-end designs but questionable code with lots of hacks, but it tends to be okay for that type of code. I got Bob here who is an old timer who has been programming since the punch card era who likes to write 10,000 line functions with gotos in them and still doesn't get the point of object-oriented programming. I got Joe here who is like a mathematical wizard but writes code no one else can understand and always make suggestions which are mathematically aligned but not necessarily so efficient from a computational standpoint. Then I got Mike here who is in outer space who wants us to port the software to iPhones and thinks we should all follow Apple's conventions and engineering standards.
Trying to satisfy everyone's needs here while coming up with a decent design was, probably in retrospect, impossible. And in everyone trying to share each other's code, I think we became counter-productive. Each person was competent in an area but trying to come up with designs and standards which everyone is happy with just lead to all kinds of instability and slowed everyone down.
Trade-Offs
So these days I've found the balance is to avoid code reuse for the lowest-level things. I use a top-down approach from the mid-level, perhaps (something not too far divorced from what you asked me to do), and build some independent library there which I can still do in a short amount of time, but the library doesn't intend to produce mini-libs that try to solve the world's hunger needs. Usually such libraries are a little more narrow in purpose than the lower-level ones (ex: a physics library as opposed to a generalized geometry-intersection library).
YMMV, but if there's anything I've learned over the years in the hardest ways possible, it's that there might be a balancing act and a point where we might want to deliberately avoid code reuse in a team setting at some granular level, abandoning some generality for the lowest-level code in favor of decoupling, having malleable code we can better shape to serve more specific rather than generalized needs, and so forth -- maybe even just letting everyone have a little more freedom to do things their own way. But of course all of this is with the aim of still producing a very reusable, generalized library, but the difference is that the library might not decompose into the teeniest generalized libraries, because I found that crossing a certain threshold and trying to make too many teeny, generalized libraries starts to actually become an extremely counter-productive endeavor in the long term -- not in the short term, but in the long run and broad scheme of things.
If you have a piece of code which could potentially be shared across a
medium size organization how would you go about informing other
members of the company that this lib/api/etc existed and could be of
benefit?
I actually am more reluctant these days and find it more forgivable if colleagues do some redundant work because I would want to make sure that code does something fairly useful and non-trivial and is also really well-tested and designed before I try to share it with people and accumulate a bunch of dependencies to it. The design should have very, very few reasons to require any changes from that point onwards if I share it with the rest of the team.
Otherwise it could cause more grief than it actually saves.
I used to be so intolerant of redundancy (in code or efforts) because it appeared to translate to a product that was very buggy and explosive in memory use. But I zoomed in too much on redundancy as the key problem, when really the real problem was poor quality, hastily-written code, and a lack of solid testing. Well-tested, reliable, efficient code wouldn't suffer that problem to nearly as great of a degree even if some people duplicate, say, some math functions here and there.
One of the common sense things to look at and remember that I didn't at the time is how we don't mind some redundancy when we use a very solid third party library. Chances are that you guys use a third party library or two that has some redundant work with what your team is doing. But we don't mind in those cases because the third party library is great and well-tested. I recommend applying that same mindset to your own internal code. The goal should be to create something awesome and well-tested, not to fuss over a little bit of redundancy here and there as I mistakenly did long ago.
So these days I've shifted my intolerance towards a lack of testing instead. Instead of getting upset over redundant efforts, I find it much more productive to get upset over other people's lack of unit and integration testing! :-D
While I think code reuse is valuable, I can see where this sentiment is rooted. I've worked on a lot of projects where much extra care was taken to create re-usable code that was then never reused. Of course reuse is much preferable to duplicate code, but I have seen a lot of very extenisve object models created with the goal of using the objects across the enterprise in multiple projects (kind of the way the same service in SOA can be used in different apps) but have never seen the objects actually used more than once. Maybe I just haven't been part of organizations taking good advantage of the principle of reuse.
The two software projects I've worked on have both been long term development. One is about 10 years old, the other has been around for over 30 years, rewritten in a couple versions of Fortran along the way. Both make extensive reuse of code, but both rely very little on external tools or code libraries. DRY is a big mantra on the newer project, which is in C++ and lends itself more easily to doing that in practice.
Maybe the better question is when do we NOT reuse code these days? We are either in a state on building using someone elses observed "best practices" or prediscovered "design patterns" or just actually building on legacy code, libraries, or copying.
It seems the degree to which code A is reused to make code B is often based around how much the ideas in code A taken to code B are abstracted into design patterns/idioms/books/fleeting thoughts/actual code/libraries. The hard part is in applying all those good ideas to your actual code.
Non-technical types get overzealous about the reuse thing. They don't understand why everything can't be copy-pasted. They don't understand why the greemelfarm needs a special adapter to communicate the same information that it used to to the old system to the new system, and that, unfortunately we can't change either due to a bazillion other reasons.
I think techies have been reusing from day 1 in the same way musicians have been reusing from day 1. Its an ongoing organic evolution and sythesis that will keep ongoing.
Code reuse is an extremely important issue - where code is not reused, projects take longer and are harder for new team members to get into.
However, writing reusable code takes longer.
Personally, I try to write all my code in a reusable way, this takes longer, but it results in the fact that most of my code has become official infrastructures in my organization and that new projects based on these infrastructures take significantly less time.
The danger in reusing code, is if the reused code is not written as an infrastructure - in a general and encapsulated manner with as few as possible assumptions and as much as possible documentation and unit testing, that the code can end up doing unexpected things.
Also, if bugs are found and fixed, or features added, these changes are rarely returned to the source code, resulting in different versions of the reused code, that no one knows of or understands.
The solution is:
1. To design and write the code with not only one project in mind, but to think of future requirements and try to make the design flexible enough to cover them with minimal code change.
2. To enclose the code within libraries that are to be used as-is and not modified within using projects.
3. To allow users to view and modify the code of of the library withing its solution (not within the using project's solution).
4. To design future projects to be based on the existing infrastructures, making changes to the infrastructures as necessary.
5. To charge maintaining the infrastructure to all projects, thus keeping the infrastructure funded.
Maven has solved code reuse. I'm completely serious.

Resources