<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>Hello Darren,</div><div><br></div><div>May I offer this point of view regarding tautological tests. They are useful for checking if your assumptions are consistent and they stay that way over multiple iterations of design modifications.<br></div><div><br></div><div>Personally I've found keeping a list of assumptions only in my head is a recipe for design errors. Fallible memory and poorly thought out logical consequences.</div><div><br></div><div>Several times I've found simple seeming functions had surprising edge cases I hadn't thought about until I actually wrote down simple obvious tests. So they are useful for making the brain juices flow while you are starting to get the shape of your program down pat.</div><div><br></div><div>Tests really serve two functions here, verification of correctness and whether the design makes sense. They are both for you and your end users. I think tautological tests are more for your benefit than the end users.</div><div><br></div><div>Tautological tests in this case have a useful purpose of allowing you to try your design out in practice and deciding if it works in a general sense of practicality and effective interface regardless of whether it gives correct output.</div><div><br>On Dec 29, 2014, at 11:28 PM, Darren Cruse <<a href="mailto:darren.cruse@gmail.com">darren.cruse@gmail.com</a>> wrote:<br><br></div><blockquote type="cite"><div><div dir="ltr">Hi Matthias just saw your reply.<div><br></div><div>Regarding the tests I like what you said about "<span style="font-size:12.6666669845581px">for a large function -- a reader quickly gets the idea of how the function works from reading some tests</span>".</div><div><br></div><div>But if I'm honest the example that you gave is the kind of example that bothers me - in that it's *not* a large function. The test you gave reminds me of the majority that I see - and it struck me recently I think what bothers me is that such tests are in effect a <a href="http://www.merriam-webster.com/dictionary/tautology">tautology</a></div><div><br></div><div>i.e. most of these tests like this, esp. since they are written by the same programmer writing the function under test, are literally just a restating of the exact same assumptions the programmer has made in writing the function. So they are *literally* redundant. Yet they must be maintained as the programmer maintains and modifies the code going forward. So there is a cost to them, but to me I honestly don't see much if any benefit.</div><div><br></div><div>Which isn't to say that good tests can't be written if they are testing a large and complex function (as you said). What I question is the common belief nowadays that they're always of value even in simple cases. </div><div><br><div>Anyway hope you'll forgive my heresy. I turned 50 this year maybe I just an old dog now too set in his ways. I know I'm very much in the minority in this view. No offense intended.</div><div><br></div><div>But more to the point - here's what I did while I should have been writing tests:</div><div><br></div><div><a href="http://htmlpreview.github.io/?https://github.com/darrencruse/pong-world-racket/blob/master/whalesong/build/pong-world.html">pong-world.rkt via whalesong</a> :)<br></div><div><br></div><div>The biggest challenge - other than what looks like some problems with multiple/deeply nested overlay/place-image positioning, is that whalesong seems to not support "on-release", so for now this works best if you click and hold where it says "hit space to serve" and then you can use your mouse and play the game against yourself.</div><div><br></div><div>This was done using the <a href="https://github.com/soegaard/whalesong">soegaard/whalesong</a> version of whalesong btw.</div><div><br></div><div>Darren</div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 29, 2014 at 8:00 PM, Matthias Felleisen <span dir="ltr"><<a href="mailto:matthias@ccs.neu.edu" target="_blank">matthias@ccs.neu.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div>TESTS: Say I want to eliminate a common pattern from your handle-key-down function. If it comes with some tests, four to be precise, a simple run -- without playing -- assures me of basic qualities. If you express tests like those below and you formulate them first, you get an idea of how to code the function. And -- for a large function -- a reader quickly gets the idea of how the function works from reading some tests. </div><div><br></div><div>(check-expect (handle-key-down initial-state "w") (set-left-moving initial-state UP-DIR))</div><div><div><br></div><div>(define (handle-key-down world a-key)</div><div> (cond</div><div> [(key=? a-key "w") (set-left-moving world UP-DIR)]</div><div> [(key=? a-key "s") (set-left-moving world DOWN-DIR)]</div><div> [(key=? a-key "up") (set-right-moving world UP-DIR)]</div><div> [(key=? a-key "down") (set-right-moving world DOWN-DIR)]</div><div> [else world]))</div><div><br></div><div>(define (set-left-moving world dir)</div><div> (set-left-paddle world (set-paddle-moving (pong-world-left-paddle world) dir PADDLE-SPEED)))</div><div><br></div><div>(define (set-right-moving world dir)</div><div> (set-right-paddle world (set-paddle-moving (pong-world-right-paddle world) dir PADDLE-SPEED)))</div></div><div><br></div><div><br></div><div>GAME PAD: I am happy to see that you used on-pad. Your game does give me an idea on how to improve the whole 'pad situation'. </div><span class="HOEnZb"><font color="#888888"><div><br></div><div>-- Matthias</div></font></span><div><div class="h5"><div><br></div><div><br></div><div><br></div><div><br></div><br><div><div>On Dec 29, 2014, at 1:43 PM, Darren Cruse wrote:</div><br><blockquote type="cite"><div dir="ltr">Thanks Matthias and it will be quite fun to tell the others at my next meetup who code reviewed this for me! :)<div><br></div><div>I'll make the changes you suggested though (forgive me) I'll have to think about what constitutes useful tests for this. Somehow I've never fully bought into TDD though I know I'm one of the last holdouts in the civilized world. :) Can I get out of it saying I was just doing this for fun? :)</div><div><br></div><div>I'm most of all pleased that you didn't see something I'd fundamentally misunderstood, e.g. that would explain why the game performed poorly on the raspberry pi.</div><div><br></div><div>fwiw Racket is the first lispy language I've ever gotten serious about learning. I'm one of those who'd been thrown off by the parens for too long. I really like using it now that I'm over the initial learning curve. I think my biggest wish would be it had a good story for doing smartphone/tablet apps, or that Whalesong was more of a going concern (not that I've tried it I wonder if this pong game would run under it without a ton of work?)</div><div><br></div><div>Thanks again for your time,</div><div><br></div><div>Darren</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 29, 2014 at 10:39 AM, Matthias Felleisen <span dir="ltr"><<a href="mailto:matthias@ccs.neu.edu" target="_blank">matthias@ccs.neu.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div>Hi Darren, thanks for the link to the repo. I cloned it, successfully played with and without sound on a mac book -- inside of drracket and from the command line-- and never observed a load over 60% for drracket and ditto for plain racket. That doesn't mean that your 100% problem doesn't exist, it's just that I can't reproduce it. </div><div><br></div><div>A couple of comments on the code: </div><div><br></div><div> -- I'd place the main function at the top of the function section of the file </div><div> right below the constant definitions and data definitions </div><div><span style="white-space:pre-wrap"> </span>[I modified 2e to bring this across but you might be reading the stable version.]</div><div><br></div><div> -- I also run (main initial-state) out of the repl not the main buffer. </div><div><br></div><div> -- Your file is missing tests. </div><div><br></div><div> -- Some functions are also missing proper signatures and purpose statements. </div><div><br></div><div>But I know "it works" see my homepage :-) </div><span><font color="#888888"><div><br></div><div>-- Matthias</div></font></span><div><div><div><br></div><div><br></div><br><div><div>On Dec 29, 2014, at 10:46 AM, Darren Cruse wrote:</div><br><blockquote type="cite"><div dir="ltr">Re:<div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span style="font-size:12.6666669845581px">Could you post the code somewhere so we can experiment with it? </span></blockquote><div><br><div>Here it is it's all in one file:</div><div><a href="https://github.com/darrencruse/pong-world-racket/blob/master/pong-world.rkt" target="_blank">pong-world.rkt</a><br></div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 29, 2014 at 8:05 AM, Matthias Felleisen <span dir="ltr"><<a href="mailto:matthias@ccs.neu.edu" target="_blank">matthias@ccs.neu.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><span><div>On Dec 28, 2014, at 9:51 PM, Darren Cruse wrote:</div><br><blockquote type="cite"><span style="border-collapse:separate;font-family:'Lucida Grande';font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:medium"><div>One thing I can see is that on-draw is called for every on-tick on all three platforms btw.</div><div><br></div><div>And even in cases where the program is idling and on-tick has simply returned the world state it was given unmodified. </div><div><br></div><div>Is that normal I wonder? Part of me thought that since to-draw is a function of the world state, and the world state hasn't changed, that it would *not* call to-draw in that case.</div></span></blockquote><div><br></div></span><div>I experimented with this 'optimization' and, if I recall correctly, it didn't make much of a difference and got in the way of imperative world programs. So I took it out. Mea culpa, I should have commented on this experiment inside the code. </div><span><div><br></div><div><br></div><div><br></div><blockquote type="cite">(but it calls to-draw for every on-tick even on the Windows machine which is using only 6% cpu - so maybe I'm wrong to look to that as the problem)</blockquote><br></span></div><div><br></div><div>My Mac-based experiments suggest that this call is not the cause of performance problems. </div><div><br></div><div>;; --- </div><div><br></div><div>Could you post the code somewhere so we can experiment with it? </div><div><br></div><div>Thanks -- Matthias</div><div><br></div><br></div></blockquote></div><br></div>
</blockquote></div><br></div></div></div></blockquote></div><br></div>
</blockquote></div><br></div></div></div></blockquote></div><br></div></div>
</div></blockquote><blockquote type="cite"><div><span>____________________</span><br><span> Racket Users list:</span><br><span> <a href="http://lists.racket-lang.org/users">http://lists.racket-lang.org/users</a></span><br></div></blockquote></body></html>