DEV Community

Cover image for Wishful Coding

Wishful Coding

Ryan Palo on December 16, 2017

Cover Image credit to René de Ruijter, at least, as far as I can tell. I've been doing the Advent of Code 2017 challenge this Advent, and I notice...
Collapse
 
codemouse92 profile image
Jason C. McDonald

This is actually really good advice!

For people who think a little differently (like me), it works the other way around, too. I think bottom-up: from the bottom of the eventual call stack upward. Thus, I will plan out my approach, sometimes stub out my top-level function like you did, and then begin to build the lowest level functions first.

By way of example, when I wrote Omission, I followed this basic workflow:

  1. Create bare minimum to display a message - basically a modified "hello, world!" I did not start with the UI yet!

  2. On paper, jot down the eventual call order. I knew the game would need the content generator for anything to work, so I'd start there. I could temporarily hardcode source content in, instead of loading from a file, so I did that. I got the program to just display some generated content.

  3. Next I added code to load content from a file. Nothing fancy here, I was only wanting to replace the hardcoded source content with material from a text file.

  4. Now I needed interaction, so I wrote the code to allow a user to answer, and for the game to verify that answer. Again, I was still only using a text-based interface. Once I had that, I added scoring. I now had a technically functional command line game.

  5. Now I added the timing-based functions. I didn't need to see any fancy timers, just to make sure the score reflected how long I took to answer.

  6. To get decent further progress, I needed the GUI, so I constructed just the gameplay screen. Don't get hung up on menus at the start!
    I only allowed myself to get the interface to work with the game as it existed. Once that worked...

  7. I began to tweak and improve the gameplay and interface to be closer to what I imagined, working in much the same manner as before: plan it out, write the lowest part first, and work my way up.

  8. Finally, I went back and added the other functionality: menus, additional gameplay modes, etc.

I'm oversimplifying, obviously, but you get the idea.

By working in this manner, I had the advantage that all my code was technically correct as I worked.

Now, a DISCLAIMER: If you think in the top-down described in the article, you probably shouldn't use my workflow. If you aren't a bottom-up programmer, this method is likely only going to confuse you. I intended this only for people who think like me. I merely wanted to show that the author's basic approach works in either direction.

Collapse
 
rpalo profile image
Ryan Palo

That’s a really good juxtaposition of the two methods. It is interesting seeing how much they have in common!

Collapse
 
ben profile image
Ben Halpern

This is great. I've gotten to doing this but hadn't really formalized it. I'm now going to practice this with a lot more intention.

Collapse
 
buckleyrabble profile image
Christopher

dude!

Collapse
 
thorstenhirsch profile image
Thorsten Hirsch • Edited

Great tip! I also do that all the time. When I'm focused and deep in the domain I don't want to jump around in the code or between the files. No, I want to write a function, component, ... in one go. That way it all makes sense later when I or someone else will read it.

In some of my programs this programming style has lead to two layers of code:

  • domain layer, here's where I've coded along the requirements in one go and everybody (with domain knowledge) should be able to read it like a book
  • library / helper layer, here are the technical details, you don't need to look here in order to understand what the program does, but most of the bugs are in here, so this is where to look if you want to know HOW it's done

However it's not always a good idea to introduce these layers into the structure of a given framework, because most frameworks give you a (more complex, more technical) structure already. Let's take MVC for example. In order to keep the controllers lean, your domain code should be in the models. But do you need to split your model layer into a domain layer and a library layer? Maybe. But if you need just a few functions in the library / helper layer a simple helper library (not part of the model layer) might be enough. Or think about concerns - normally they should contain domain code (shared behaviour between multiple models), but it's also a good place to fully implement your functions in order to keep them out of your models, so you can use them as a library layer as well.

Collapse
 
franga2000 profile image
Miha Frangež • Edited

I've been doing this for a while now and my code has been noticeably cleaner.

This is also a great way to introduce the idea of methods to complete beginners. I used this recently in a Java intro class.

In the beginning we pretended many "complicated" methods already existed (readNumber(), isPrime(int), etc.), but as we learned new things, we started filling them in. That way, we could focus on the program logic before learning about all the language specifics (which is a very good thing for when they switch to a different language).

Collapse
 
rpalo profile image
Ryan Palo

That’s really cool! I hadn’t thought about using this idea while teaching. I can see how that would make functions/methods more natural

Collapse
 
rpalo profile image
Ryan Palo

Just in case you didn’t get enough #goodboye
Another picture of Willy

Collapse
 
mangekalpesh profile image
Kalpesh Mange

He's a goodbwoy 😍💙🙌

Collapse
 
akajb84 profile image
Neesha Desai

This to me is the purpose of pseudocode. Planning out what you want to happen, without worrying about all the nitty-gritty details to start.

I do something similar when I code, especially if it's a larger problem. Often, I use comments, to first put down my thoughts similar to "do this, then if this, do that, else do this." After, I can start coding by tackling one comment at a time (which is a lot less daunting). And, usually each comment a good place to test that it's working as expected.

Collapse
 
enriquemorenotent profile image
Enrique Moreno Tent

"Use Methods You Wish You Had". This is exactly the key. We try so often to do what we want with what we have, instead of thinking what we wish we had.

Collapse
 
ham1 profile image
Graham Russell • Edited

I've heard this referred to as error driven development. I try to use it when I remember. F2 and alt+Enter in IntelliJ help speed this up as well! Goto next error and the "magical fix my code" key combo.

This also often leads to cleaner code, i.e. methods with code at one level of abstraction, rather than a mix (and often mess)

Collapse
 
rpalo profile image
Ryan Palo

Yep! I have had more than a few ‘rake test’ /NoMethodError/head-desk moments.

Collapse
 
buckleyrabble profile image
Christopher

dude!

Collapse
 
wrongabouteverything profile image
wrong-about-everything

That's what Fred Brooks wrote about in Mythical man-month. He proposed to build a higher-level skeleton first, the one that just compiles but implements no useful behavior. Then delving deeper and deeper, considering fail scenarios and edge cases. Though I guess pretty much everybody has came to this approach already by the time he or she has read the book.

Collapse
 
rpalo profile image
Ryan Palo

Neat! I'll have to check that out. He probably spells it out more clearly and concretely than what I have in my head, so that should be helpful.

Collapse
 
julioolvr profile image
Julio Olivera

I love this approach 🙌

Personally, I think this helps a lot to organize the code in reasonable levels of abstraction - if I think in terms of high-level methods or functions that I’d like to have, I’ll be less tempted to reach for the file system or make an HTTP request when I should be thinking in terms of my business classes. Getting to the lower levels usually comes naturally out of filling in the missing methods.

Collapse
 
jon_cage profile image
Jon Cage

I often do this but I take one more step back; Write the overall method that will do the job but fill it with comments indicating my intentions before I actually write the code. I find this really helps make you think about what you need before you commit to decided on the specifics of what you're going to implement.

For something really trivial like your example above, writing it in code works but in more complicated situations it can be another helpful trick to break a problem down.

Collapse
 
developius profile image
Finnian Anderson

This is great! It also plays nicely with the practices of TDD/BDD where you write the test and then the code. Being able to “use” the API (even just mocking it out) makes it very clear on what it should do and helps you implement it.

Collapse
 
t4rzsan profile image
Jakob Christensen

This method sounds very much like how you would do TDD. You write your tests before you write any code and your tests thus become your documentation and prototyping.

Also, some tools have built in support for this. Take Visual Studio for example. It gives you keyboard shortcuts to quickly create new types and methods as you type your code.

Collapse
 
vikramj74 profile image
Vikram Jaswal

Cool technique. I recently started planning on tools like creately, before programming. I try and imagine the complete solution set on the digital whiteboard, and then run through it to get out the problems. After many iterations, I arrive at a sensible looking design. Then I start implementing the code bottom up, with TDD. Thinking this ways saves me a lot of time and effort, yet it results in better quality software.

Collapse
 
rpalo profile image
Ryan Palo

Cool tip! I hadn’t heard of creately, I’ll have to check it out.

Collapse
 
toppk profile image
toppk • Edited

Sometimes I won't want the code to break "compile" so I'll just comment the wishful code, but I always will make a runtime failure if the function isn't complete (e.g. return False, raise exception, etc.)

it's always good to exercise failure paths early

Collapse
 
z0al profile image
z0al • Edited

Great advise, thanks 👍

What if I told you that I sometimes draw the logo of my app, and write some documentation of possible usage before I even write a single line of code? I hate it, but this how I work :/

P.S. Logo design usually takes forever to get it done because I'm not even designer hahaha

Collapse
 
rhymes profile image
rhymes

Very good article!

It's also what we should do when doing TDD (which is not often enough, at least for me :D): write the interface, check results and then write the code to make the test pass, one step at the time.

Collapse
 
rpalo profile image
Ryan Palo

Yep! That’s what I do by profession. I work at ProtoQuick. We make a lot of prototypes and even production. One of the funnest molds I designed recently was for the ProFroster, for bakers!

Collapse
 
nektro profile image
Meghan (she/her) • Edited

Just started real work on a big project I've been wanting to make for while now, and this is really helping! Great article :D

Collapse
 
jochemstoel profile image
Jochem Stoel

This is profound wisdom. Future me appreciates this.

Collapse
 
narshim profile image
Narshim

Awesome. We all do that. Making this as an habit is what really requires

Collapse
 
katylava profile image
katy lavallee

Solid punchline before the wrap up.

Also, great tip!

Collapse
 
rpalo profile image
Ryan Palo

Thanks! Glad you liked it.