I finally hunted down a deep dive into how properties work that you should read top to bottom: [Apex Properties](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_properties.htm) from the `Apex Developer Guide`.

---

If you want to declare a setter, you must set the property equal to the incoming `value`.

    public String userInput
    {
        get { return userInput; }
        set { userInput = value; }
    }

You can also use the simplified form here since you are not doing anything more fancy:

    public String userInput { get; set; }

The problem with your code as posted was that you set `userInput` to itself, so it is always `null`.

---

[@sfdcfox](https://salesforce.stackexchange.com/users/2984/sfdcfox) has astutely pointed you towards [Building a Custom Controller](https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_controller_custom.htm) from the `Visualforce Developer Guide`, but I think his own explanation is actually a better read for you here: https://salesforce.stackexchange.com/questions/71700/apex-controllers-what-do-the-get-set-do

---

There's also a useful link from Summer 08 on the `Salesforce Developers Blog` called [Property Accessors in Apex in Summer ’08](https://developer.salesforce.com/blogs/developer-relations/2008/06/property-access.html).

> Basically, instead of writing the following in a class:

>     String prop;
>     public String getProp() { return prop; }
>     public void setProp (String p) { prop = p; }

> we can now write this:

>     public String prop {get; set;}

> Many keystrokes saved. Note that the latter doesn’t actually generate a `getProp()` method, see below.

> **Syntax examples**

> That’s actually an abbreviated abbreviated syntax. The get and set can be expanded somewhat to contain custom code. For example:


>     public String prop { get {return prop;} set {prop = value;} }

> A couple of things to note here:

>- The `get` body must end in a return, sensibly…
>- The `set` body receives an implicit argument called `value` of the same data type as the property.

> You can also omit a get or a set, in which case the property becomes write or read only, respectively.