19

As a companion to the question "What was the first programming language to have 'printf'?", which language had the first scanf?

It doesn't have to be literally called scanf, but I am looking for the following:

  • A procedure, subroutine, function, or statement with the purpose of reading textual items from a file or input device.
  • Takes a variable number of parameters, at least one of which specifies the number and format of the items to read.
  • As this is a "first" question, you need to specify the year such a feature was introduced. I am not looking for every language with such a feature.

The C scanf appears to have been introduced sometime between 1972 and K&R first edition in 1978, so that's an upper bound to the answer.

4
  • 4
    To narrow the dates down a little, in the Unix world scanf first appeared in Mike Lesk’s Portable C Library, which was added as iolib in V6 in 1975. Commented Aug 17, 2021 at 9:40
  • 4
    Under what conditions does a library count as part of a language? (Honest question, I don't know the answer.)
    – LarsH
    Commented Aug 17, 2021 at 14:13
  • 1
    @LarsH: I would considered a library that is delivered or installed with an implementation of the language to count as part of the language.
    – DrSheldon
    Commented Aug 17, 2021 at 15:50
  • I don't know enough of the early history of COBOL to make this a definitive answer, but in COBOL you declare the format of a file declaratively in its data description, then you issue a READ statement, and it populates a record whose structure is defined by the data description. Arguably much more robust, though less dynamic, than what C has to offer. It doesn't do it with a variadic function call, but who needs that if you've got rich structured data types? Commented Aug 18, 2021 at 23:26

3 Answers 3

31

Fortran: October 1956.

See The Programmer's Reference Manual for Fortran on the IBM704, Chapter 5.

In the question about printf Fortran was explicitly excluded, but I don't see why it fails to meet the criteria of this question. The I/O statement certainly "has a parameter which specifies the format of the items to read," though the definition of the format was separated out, with the obvious advantage that identical format definitions can be used in multiple I/O statements without unnecessary repetition.

The format can be separated out in scanf by specifying it as a variable instead of a constant, of course.

Later versions of Fortran, which included character data types, allowed the format specification to be embedded within the I/O statement, if desired.

10
  • Maybe FORMAT should be disqualified on the requirement that there be an argument that "specifies the number ... of the items to read." :-) If I recall correctly, it's the de facto number of variable/array elements that appear in the READ that determine how many items are read. "Not using all the FORMAT" is ok, and coming to the end of the FORMAT is governed by baroque rules of where to resume scanning. I suspect Algol 68 has similar features.
    – dave
    Commented Aug 17, 2021 at 14:10
  • 5
    @another-dave Well, scanf just replaces the "built-in baroque logic" with user-written baroque logic to loop around the scanf statement. IMO the real genius of the Fortran design was identifying a subset of the general formatting problem which was "good enough" to do something useable almost all of the time.
    – alephzero
    Commented Aug 17, 2021 at 14:33
  • @alephzero: Were the formatting operations in FORTRAN processed as calls to variadic functions, or would they have required compiler logic to translate what looked like variadic calls into sequences of calls to functions that would each expect a fixed set of arguments?
    – supercat
    Commented Aug 17, 2021 at 16:11
  • @supercat I don't think the a compiler could have converted them into calls with a predefined fixed sequence of arguments, because (1) as another-dave pointed out, re-using the format items follows it own logic (depending on the format string itself) and (2) the number of input items can be read as part of the input data - e.g 10 FORMAT(3I5) and then READ(*,10) M, (N(J),J=1,M) is valid Fortran. The first input data line contains M and the first two elements of array N, subsequent lines each contain the next three elements of N, ignoring any excess input items on the last line.
    – alephzero
    Commented Aug 17, 2021 at 17:32
  • 1
    @supercat: re: On a FORTRAN implementation which doesn't have a stack, it would be impossible for a function to accept a variable number of arguments - I don't see this at all. If your calling sequence is, say, a jump-to-subroutine followed by sequence of addresses of arguments (pass-by-ref), then I can imagine a number of ways to determine the number of actual-args, and adjust the return appropriately.
    – dave
    Commented Aug 17, 2021 at 19:29
14

I think the FORTRAN answer is valid within the terms of this question, but for orthogonality with the 'printf' answer, I think we need to mention Algol 68 again.

Algol 68 provided 'readf', for formatted input from standard in, and 'getf', for formatted input from a specific file channel.

The names given here are from the Revised Report, published 1974, but the functionality was present in the original 1968 Report under different names, 'out' and 'outf'.

In both Reports, these facilities were implemented as procedure calls, with format as a mode defined in the language, with its own denotation (i.e., a format was not just a string).

1
6

Perhaps the real question shouldn't be which language "had" the first scanf function, but rather which language first allowed variadic functions to be written in user code. That would have been possible in B, and I am unaware of any earlier languages that would have supported it.

Other earlier languages allowed programmers to supply an arbitrary number of arguments for items to be read, but the compiler would have known how many arguments were being passed, and generated code to handle that many arguments. In Pascal, for example, ReadLn(A, B, C); would have been equivalent to Read(A); Read(B); Read(C); ReadLn; What would have made the behavior of scanf different is that a B or C compiler could (and typically would) have been completely agnostic to the fact that the function needed special handling to accommodate variable numbers of arguments, and would have processed calls to scanf no differently from calls to any other function.

10
  • 1
    That sounds like a reasonable -- but separate -- question.
    – DrSheldon
    Commented Aug 17, 2021 at 15:52
  • I am unaware of languages prior to B that allowed functions to actually be passed arbitrary variable numbers of arguments. Instead, compilers for those language would translate each construct that looked like variadic function call into one or more calls to functions that each expected a fixed number of arguments. The reason I focus on the "user code" question is that compilers for C and likely B as well would have come bundled with an implementation of scanf well before such a function was formalized as part of a standard library, but I think it's fair to back-date language support...
    – supercat
    Commented Aug 17, 2021 at 16:04
  • ...to the time when a compiler vendor demonstrated for users how to achieve such functionality. Having to copy in a blob of source text is less convenient than just #include <stdio.h>, but the reason the function became part of the Standard library is that programmers would often include a definition of the function and then treat it as part of the language, rather than writing purpose-specific functions to handle input parsing.
    – supercat
    Commented Aug 17, 2021 at 16:09
  • I agree that it's a significant development in computer languages, but it merits a separate question.
    – DrSheldon
    Commented Aug 17, 2021 at 16:12
  • 1
    @supercat Lisp supported it since the beginning.
    – texdr.aft
    Commented Aug 17, 2021 at 20:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .