Test the Four Truths About a Keypress

(Edited 12Sep2021 for terminology)

Sometimes a code writer might want to know more things about a key than what can be learned from the blocks built into Snap! A custom block that tests the Four Truths about a key could be useful.

Snap! has great blocks for checking a couple of things about keyboard key at one moment in time. The hat,
fires at the moment when the key goes down. The predicate block,
tells you whether the key is down at the moment you check it. Very useful, as far as they go.

Some people on the Forum have wished for a block that would detect only the first press of a key. In other words, they want to run some code only once when a key goes down, but not while the key remains held down. They want to avoid a runaway keypress situation like the following:


Oops! I left my finger down on that key too long!

The trick is to test how the key changes from one test of the key to the next test. It wants a test that remembers whether the key was down or up the last time it was tested. Comparing the two test results reveals the Four Truths about a keypress. The key was:

  1. UP last time; it changed; now it is DOWN. The key went down.
  2. DOWN last time; it is DOWN now, also. The key remains down.
  3. DOWN last time; it changed; now it is UP. The key went up.
  4. UP last time; it is UP now, also. The key remains up.

Code that keeps track of prior test results can be designed to distinguish between Truth #1 and Truth #2. Such code can help to avoid a runaway keypress.

Begin edit of 12Sept2021

How nice it would be to wrap the code neatly inside a single, custom block. That can be done by writing a regular procedure (that is, a custom block) for the specific key to be tested. A "block variable" in the procedure can remember the result of a prior test.

To test several, different keys, you could duplicate the block definition then edit it to change which key is to be tested. The downsides of that approach include increased workload for the code writer and the possibility of errors in the duplicating or editing.

It would be even nicer to have one custom block that made it easy to create blocks that test the Four Truths for different keys of the coder's choice. This sounds like a job for a "higher order procedure". Quoting the Snap! Manual,

A higher order procedure is one that takes another procedure as an input, or that reports a procedure.

In this situation, we want a higher order procedure that not only remembers a test result from one call to the next but also does both of the things that make higher order procedures so special. We want it to:

  • take the key [ ] pressed? block as an input, selecting the letter to be tested
  • report a (second, different) procedure that
    • executes the test,
    • compares the result to the previous test,
    • determines which of the Four Truths is true (setting the others to false),
    • and saves the test result for next time.

That second procedure is the one that actually evaluates the Four Truths. However, it emerges with no name. It is "anonymous". To call it in an intuitive way, we may give it a name. This is done by creating a variable then setting its "value" to be the procedure reported by the higher order procedure.

End edit of 12Sep2021

Here's code using such a block. It operates a "forever loop" but increments the value of x only once each time the "A" key is pressed down.


You can hold the "A" key down as long as you like; the value will not increase. Release the "A" key then press it again. The value of x increases by one. It increments only when the key was up then went down.

Begin edit of 12Sept2021

The blue "sensor" block in there, named "perform key test <key [a] pressed?>" is a "lambda". It specifies which key to test. As a result, the second function that that will be reported out tests only the "A" key.

End edit of 12Sept2021

Test the "A" key by putting the variable into a "call" block. The call block has an input where you can type a message to the function stored inside it. The message can tell the function which one of the four Truths to test:

  • went down
  • remains down
  • went up
  • remains up

There is also a message for debugging purposes:

  • list all

It would be useful in a "say" block:


The code for this block and the demo shown here is available in a shared project at the following URL: https://snap.berkeley.edu/snap/snap.html#present:Username=codegeezer&ProjectName=keyChangeBlock.

This is an unusual use of language. I think most programmers would understand "a lambda function" to mean "a function created using lambda," i.e., an anonymous function, which is a more commonly used term. A function that returns a function, or takes a function as input, is a higher order function. If you want to distinguish the case of a function that returns a function, you could say "function-valued function."

And in some circles "rather than a value" would be considered a wash-your-mouth-out-with-soap offense; the whole point is that functions are perfectly good values, just as much so as numbers or strings or lists.

The part about an internal function (one made by a lambda expression inside another function) being able to remember its past state is important; it's how you use functions to implement OOP. But you should note that there's another way for Snap! functions to remember past state, namely, block variables. (Look it up in the manual...)

You note here the pathetic bleatings of a weak and ill-furnished mind striving to express knowledge. I wrote it in terms that relate to experiences gained in my misspent youth. :slight_smile:

Apologies for giving offense, and a plea for mercy...

Not offended; I didn't say I wanted to wash your mouth out with soap! :~P


I already gave up and surrendered. Y'all can stop shooting!

I tried to help, but only tried your patience.

I want to see it, but:
Screenshot (100)

Aww, don't be mad. w_w_w isn't shooting at you, just looking for Knights of the Lambda Calculus points. :~)

Just "WWW" if you have to shorten it, please. My username would be "WarpedWartWars".

Sorry. Will do.

Please try again. Two ways to win:

  1. It is published. Search the main Berkeley Snap! web site for "keyChangeBlock".
  2. It is shared. Click [Snap! 6.9.2 Build Your Own Blocks](Snap! 6.9.2 Build Your Own Blocks]

Thank you.

I just checked again and it works! Also, just in case you don't know, you made a class!

I edited the initial post on 12Sep2021, as clearly marked in the post, in an effort to address the initial critiques. I hope it steps toward the general direction of betterness.

It's been long and long ago since a teacher whacked my knuckles over sloppy writing. But no old is too old for learning, and now, as then, I pursue penance by correction.

Ah, no wonder you have this punitive view of how teaching happens... :~/