Repository: go
Issue: proposal: new package simpleinput for Go education
Labels: Proposal

## Problem:

Every few months, someone will post on Reddit that they're trying to make an intro-to-CS-style input prompt and they're confused why their code using `fmt.Scan*` doesn't work (inevitably because the input has a space and they're ignoring errors). I think that just for the use case of education, there should be something that does the thing that they want.

<details>
<summary>Here are some typical posts</summary>

* https://www.reddit.com/r/golang/comments/alvdhl/force_golang_to_scan_a_number_instead_of_a_single/
* https://www.reddit.com/r/golang/comments/atlehx/flushing_standard_input_before_scanf/
* https://www.reddit.com/r/golang/comments/2h5qnw/using_numerical_values_from_slices/
* https://www.reddit.com/r/golang/comments/wv1i2z/can_someone_tell_me_what_im_doing_wrong_im_trying/
* https://www.reddit.com/r/golang/comments/hkz1im/what_is_the_most_idiomatic_way_of_getting_input/
* https://www.reddit.com/r/golang/comments/8umvpt/unclear_on_scan/
* https://www.reddit.com/r/golang/comments/4hktbe/read_user_input_until_he_press_ctrlc/
* https://www.reddit.com/r/golang/comments/tq3wpc/scanln_and_scanf_jump_after_entering_string_value/
* https://www.reddit.com/r/golang/comments/qja60y/issues_with_fmtscanf_reading/
* https://www.reddit.com/r/golang/comments/kee82p/i_am_bit_confused_about_golangs_scanf/
* https://www.reddit.com/r/golang/comments/bkqos6/differences_between_scan_functions/
* https://www.reddit.com/r/golang/comments/whfi8p/question_about_fmtscan/
* https://www.reddit.com/r/golang/comments/p2tnio/in_golang_is_there_is_any_way_to_take_input/
* https://www.reddit.com/r/golang/comments/s85xxl/having_trouble_with_scanning_input_new_to_language/

You can find more by searching site:https://reddit.com/r/golang fmt.scan.
</details>

New programmers aren't a huge source of new Go users. On the other hand, even if most Go programmers come from other languages, it is convenient when learning the language to be able to write simple intro-to-CS-style question/response programs to get a feel for the language. There ought to be something very simple that novice can find without knowing anything about Go or IO. Obviously, novices could and probably should be using bufio.Scanner already, but they aren't finding it today. Instead they look in fmt (because they are already using fmt.Println) and find the Scan family of functions. Then they are frustrated when it does not work the way they expect.

## Proposed solutions

Proposed solution one is simple: mark the Scan functions as deprecated to hide them from the documentation. Even Rob Pike [regrets adding the Scan functions](https://github.com/golang/go/issues/12275#issuecomment-133796990). 

Proposed solution two is to add a new package just for education purposes.

```go
// Package simpleinput provides function for basic reading from os.Stdin.
// Functions in this package are concurrent safe. 
// For better performance, use bufio directly.
package simpleinput

// SetSource sets the source that simpleinput buffers reads from. 
// By default, it uses os.Stdin.
func SetSource(io.Reader)

// Source returns the underlying io.Reader that simpleinput buffers reads from.
func Source() io.Reader

// Error returns the last error encountered by simpleinput, if any.
func Error() error

// Read reads from Source until it receives an error, typically io.EOF.
func Read() string

// ReadLine reads one line from Source. It removes "\n" and "\r\n" from its output.
func ReadLine() string

// ReadLines reads Source until it encounters an error.
// It removes "\n" and "\r\n" from its output.
func ReadLines() []string
```

Obviously, none of this is strictly necessary, but it would help Go learners, particularly those new to programming.

Cf. #54620

- - - -

Edit: Proposed API is now:

```go
// Package simpleinput provides function for basic reading from os.Stdin.
// Functions in this package are concurrent safe. 
// For better performance, use bufio directly.
package simpleinput

// SetSource sets the source that simpleinput buffers reads from. 
// By default, it uses os.Stdin.
func SetSource(io.Reader)

// Source returns the underlying io.Reader that simpleinput buffers reads from.
func Source() io.Reader

// Read reads from Source until it receives an error. 
// If the error is io.EOF, it returns a nil error.
func Read() (string, error)

// ReadLine reads one line from Source. It removes "\n" and "\r\n" from its output.
// If it encounters an io.EOF, it returns the error.
func ReadLine() (string, error)

// ReadLines reads Source until it encounters an error.
// It removes "\n" and "\r\n" from its output.
// If the error is io.EOF, it returns a nil error.
func ReadLines() ([]string, error)
```