167
\$\begingroup\$

In this challenge, users will take turns completeing three fairly simple coding tasks in programming languages that are allowed to be progressively older.

The first answer must use a programming language that was made in the year 2015. Once there is at least one answer from a 2015 language, answers may use programming languages that were made in 2014. Similarly, answers that use languages from 2013 are not allowed until there is at least one 2014 answer.

In general, the use of a programming language from the year Y is not allowed until an answer using a language from the year Y+1 has been submitted. The only exception is Y = 2015.

Finding Your Language's Year

To answer this question, you must know the year your programming language was "made in". This is, of course, a subjective term; some languages were developed over the course of multiple years, and many languages are still being upgraded every year. Let the year a language was "made in" be the first year an implementation for that language appeared in the general public.

For example, Python was "made in" 1991, though its development had been in progress since 1989, and version 1.0 wasn't released until 1994.

If this year is still subjective, just use your common sense to choose the most appropriate year. Don't get bogged down in slight disagreements about year choices. Please provide a link to a source that says when your language was made.

Different versions or standards of a programming language (e.g. Python 1, 2, 3) are counted as the same language with the same initial year.

So, unless your language's year is 2015, you can only submit your answer once an answer has been submitted whose language's year is the year just before yours.

If a valid answer with the same year as yours already exists, then you may answer. It doesn't matter if your language was developed earlier or later in the year.

Tasks

You must complete Tasks 1 through 3. Task 0 is optional.

These tasks were more or less chosen to correspond to three important aspects of programming: providing output (Task 1), looping (Task 2), and recursion (Task 3).

Task 0 - Language History (optional)

Write at least a paragraph explaining the history of your chosen programming language: who developed it, why, how, etc. This is especially encouraged if you personally were around when the language came into being, and maybe even played a part in its development. Feel free to relate personal anecdotes about the effect the language had on you or your job, or anything like that.

If you're too young to know much about the history of your language without a lot of research, consider leaving a note to older users that says they can edit your post and add in some first-hand history.

Task 1 - "Hello, World!" Variant

Write a program that prints

[language name] was made in [year made]!

to your language's standard output area (stdout for most recent languages).

For example, if the language was Python, the output would be:

Python was made in 1991!

Task 2 - ASCII Art N

Write a program that lets the user enter in an odd positive integer (you may assume the input is always valid), and prints out an ASCII art letter N made using the character N.

If the input is 1, the output is:

N

If the input is 3, the output is:

N N
NNN
N N

If the input is 5, the output is:

N   N
NN  N
N N N
N  NN
N   N

If the input is 7, the output is:

N     N
NN    N
N N   N
N  N  N
N   N N
N    NN
N     N

The pattern continues on like this. The output may contain trailing spaces.

Task 3 - GCD

Write a program that lets the user enter in two positive integers (you may assume the input is always valid), and prints their greatest common divisor. This is defined as the largest positive integer that divides both numbers without leaving a remainder. It can be readily calculated using the Euclidean algorithm.

Examples:

8, 124
12, 84
3, 303
5689, 21
234, 8766

You may use a built in function but try finding out if it was there in the first version of your language. If not, try not using it.

Rules

  • You may answer multiple times, but each new answer must use a language made at least 5 years before the language in your last answer. So if you answered with a 2015 language, you couldn't answer again until 2010 languages are allowed. If you start with a 2010 answer, you can't make a 2015 answer your second answer because 2015 is not before 2010.
  • If possible, write your code so that it would have worked in the very first version of your language (or as old a version as possible). (This is not a requirement because finding old compilers/interpreters for some languages may be difficult.)
  • Refrain from posting a language that has already been posted unless the posted answer has significant errors or you have a very different way of completing the tasks.
  • Golfing your code is fine but not required.
  • A trailing newline in the output of any program is fine.
  • For tasks 2 and 3, all input values below some reasonable maximum like 216 should work (256 at the very least).
  • Your language must have existed before this question was posted.
  • Very old programming languages may have different forms of input and output than what we think of today. This is fine. Complete the tasks to the best of your ability in the context of your language.

Scoring

Your submission's score is:

upvotes - downvotes + (2015 - languageYear) / 2 

Thus, 0.5 is added to the vote count for every year before 2015, giving the advantage to older languages. The submission with the highest score wins.

Answer List

The Stack Snippet below lists all the valid answers according to their language year.

You must start your post with this Markdown line to ensure it is listed correctly:

#[year] - [language name]

For example:

#1991 - Python

The language name may be in a link (it will be the same link in the answer list):

#1991 - [Python](https://www.python.org/)

Answers that don't follow this format, or have a year that is not allowed yet, or come from a user that already answered in the last 5 years are marked as invalid.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script>$(function(){function e(e,r){var a="https://api.stackexchange.com/2.2/questions/48476/answers?page="+e.toString()+"&pagesize=100&order=asc&sort=creation&site=codegolf&filter=!YOKGPOBC5Yad160RQxGLP0r4rL";$.get(a,r)}function r(e){if(e.items.forEach(function(e){var r=e.link,a=e.owner.display_name,i=e.body.match(/<h1\b[^>]*>(\d{4}) - (.*?)<\/h1>/);if(i&&i.length>=3)var h=parseInt(i[1]),u=i[2];h&&u&&n>=h&&h>=t&&(!d.hasOwnProperty(e.owner.user_id)||d[e.owner.user_id]-h>=p)?(d[e.owner.user_id]=h,h==t&&--t,o.hasOwnProperty(h)||(o[h]=[]),o[h].push({language:u,user:a,link:r,score:e.score+(n-h)/2})):s.push(' <a href="'+r+'">'+a+"</a>")}),e.has_more)runQuery(++a,r);else{for(var i=n,h=[];o.hasOwnProperty(i);){for(var u=$("<tr>").append($("<td>").text(i.toString())),l=$("<td>"),c=$("<td>"),g=$("<td>"),f=0;f<o[i].length;f++){var v=o[i][f];l.append(v.language),c.append($("<a>").html(v.user).attr("href",v.link)),g.append(v.score),f+1<o[i].length&&(l.append("<br><br>"),c.append("<br><br>"),g.append("<br><br>"))}u.append(l).append(c).append(g),h.push(u),--i}$("#answers").find("tbody").append(h),s.length>0?$("#invalid").append(s):$("#invalid").remove()}}var a=1,n=2015,t=n-1,p=5,o={},s=[],d={};e(1,r)})</script><style>html *{font-family: Helvetica, Arial, sans-serif;}table{border: 4px solid #a4a; border-collapse: collapse;}th{background-color: #a4a; color: white; padding: 8px;}td{border: 1px solid #a4a; padding: 8px;}div{font-size: 75%;}</style><table id='answers'> <tr> <th>Year</th> <th>Language</th> <th>User (answer link)</th> <th>Score</th> </tr></table><div id='invalid'><br>Invalid Answers:</div>

\$\endgroup\$
  • 2
    \$\begingroup\$ This should help. \$\endgroup\$ – swish Apr 6 '15 at 9:10
  • 20
    \$\begingroup\$ Wikipedia has a list for everything: this one for non-esoteric languages by year. \$\endgroup\$ – Sanchises Apr 6 '15 at 12:30
  • 2
    \$\begingroup\$ Should Task 3 actually use recursion or is it enough that it produces the correct result? If I need to write my own GCD function I usually just use a loop but I wrote a recursive one specially for this challenge. There are many submitted answers that just use a loop. \$\endgroup\$ – CJ Dennis May 3 '15 at 2:51
  • 5
    \$\begingroup\$ I feel like making a second account just to get us past 1971. \$\endgroup\$ – marinus May 5 '15 at 10:49
  • 5
    \$\begingroup\$ If we can get it back to 1952, I have someone spinning up a historic machine that could do 1951 (Pegasus) solutions and test them! \$\endgroup\$ – Brian Tompsett - 汤莱恩 May 19 '15 at 18:19

96 Answers 96

15
\$\begingroup\$

1965 - Atlas Autocode

Atlas Autocode (AA) was developed as a high level language to program the Ferranti Atlas Computer developed in Manchester. This was a particularly important machine in the history of computing in that it held the patents for the first virtual memory and reverse virtual memory system.

The source of the Atlas Autocode compiler (written in Atlas Autocode) is available, and so is an Atlas Emulator, but at present there is no working copy of the compiler on the Emulator, as so these programs cannot be executed at present.

An interesting feature of AA is that it was developed specifically for an input device known as a Friden Flexowriter and the character set reflects that device. In particular reserved words are underlined.

Task 1

b̲e̲g̲i̲n̲
i̲n̲t̲e̲g̲e̲r̲ y
y = 1965
c̲a̲p̲t̲i̲o̲n̲ Atlas s/ Autocode s/ was s/ made s/ in; print (y,4,0); newline
s̲t̲o̲p̲
e̲n̲d̲_o̲f̲_p̲r̲o̲g̲r̲a̲m̲

Task 2

b̲e̲g̲i̲n̲
i̲n̲t̲e̲g̲e̲r̲ n
read(n)
c̲o̲m̲m̲e̲n̲t̲ The cycle statement is the familiar DO
c̲y̲c̲l̲e̲ i = 1, 1, n
   c̲y̲c̲l̲e̲ j = 1, 1, n
     i̲f̲ j = 1 o̲r̲ j = i o̲r̲ j = n t̲h̲e̲n̲
       c̲a̲p̲t̲i̲o̲n̲ N
     c̲o̲m̲m̲e̲n̲t̲ But the unless statement has to be used as there is no else clause for the if
     u̲n̲l̲e̲s̲s̲ j = 1 o̲r̲ j = i o̲r̲ j = n t̲h̲e̲n̲
       c̲a̲p̲t̲i̲o̲n̲ s/
   r̲e̲p̲e̲a̲t̲
   newline
r̲e̲p̲e̲a̲t̲
s̲t̲o̲p̲
e̲n̲d̲_̲o̲f̲_̲p̲r̲o̲g̲r̲a̲m̲

Task 3

b̲e̲g̲i̲n̲
i̲n̲t̲e̲g̲e̲r̲ fn gcd(i̲n̲t̲e̲g̲e̲r̲ a,b)
    i̲f̲ a = 0 t̲h̲e̲n̲ r̲e̲s̲u̲l̲t̲ = b
    i̲f̲ b = 0 t̲h̲e̲n̲ r̲e̲s̲u̲l̲t̲ = a
    r̲e̲s̲u̲l̲t̲ = gcd( b , a - b)
    e̲n̲d̲

i̲n̲t̲e̲g̲e̲r̲ i, j
read (i,j)
print (gcd(i,j),4,0) ; newline
s̲t̲o̲p̲
e̲n̲d̲_̲o̲f̲_̲p̲r̲o̲g̲r̲a̲m̲

\$\endgroup\$
  • \$\begingroup\$ The underlining is hard to get right on all browsers. If it does not display properly - try another browser. If you know how to do it better let me know! \$\endgroup\$ – Manchester MUSS Alumni May 24 '15 at 21:14
  • \$\begingroup\$ It is possible to create a function in bash (also ksh or zsh) like: underline is a function underline () { while (($#)); do a=$1; for ((i=0; i<${#a}; i++)) do printf '%s\u0332' "${a:i:1}"; done; printf " "; shift; done; echo } and then do underline begin integer stop to get the undelined equivalents. Then, just copy and paste. \$\endgroup\$ – Isaac Jun 27 at 21:32
14
\$\begingroup\$

2014 - Swift

Swift is a multi-paradigm language released by Apple in the summer of 2014, although Chris Lattner began work on it way back in 2010. Swift largely follows C syntax and borrows features from Objective-C, Rust, Haskell, Ruby, Python, C# and many other languages, such as closures, generics, protocols/interfaces, categories/extension methods, tuples, and non-nullability and immutability by default.

All these examples can be run at SwiftStub.

Task 1

println("Swift was made in 2014!")

Task 2

Swift has flexible switch statements allowing constants, ranges and enums (which are intended to be algebraic types) allowing for fairly powerful pattern matching.

func asciin(n:Int) -> String {
    var r = 0;
    return [Int](0..<n*n).reduce("", { msg, next in
        switch next % n {
            case 0, r: return msg + "N";
            case n-1: r++; return msg + "N\n";
            default: return msg + " ";
        }
    }
)}

Task 3

Tuples make this easy, but because parameters are immutable we need to create a new mutable tuple from them.

func gcd(a:Int, b:Int) -> Int {
    var g = (a, b);
    while(g.1 > 0) {
        g = (g.1, g.0 % g.1);
    }
    return g.0;
}
\$\endgroup\$
14
\$\begingroup\$

2007 - Clojure

Clojure is a general-purpose programming language with an emphasis on functional programming. It is a dialect of the Lisp programming language. It runs on the Java Virtual Machine, Common Language Runtime, and JavaScript engines.

You can find a online Clojure REPL at Try Clojure. It also includes a short tutorial on the basics of Clojure.

Task 1

(println "Clojure was made in 2007!")

Task 2

(defn ascii [n]
  (doseq [i (range 0 n 1)]
    (doseq [j (range 0 n 1)]
        (printf (if (or (= i j) (= j 0) (= j (dec n))) "N" " "))
    )
    (printf "\n")
  )
)

(ascii (read))

Task 3

(defn gcd [a b]
    (if (zero? b) a (recur b (mod a b)))
)
(println (gcd (read) (read)))
\$\endgroup\$
  • 1
    \$\begingroup\$ Iirc, (or) can accept any number of arguments. (inc j) and (inc i) both do nothing (their return values aren't captured). I would also recommend to return the string instead of just printing it (Clojure isn't exactly meant to be procedural). Hint: (for) \$\endgroup\$ – seequ Apr 10 '15 at 18:26
  • \$\begingroup\$ @Sieg Thanks! I'm new to Clojure and am still learning. \$\endgroup\$ – Zero Fiber Apr 11 '15 at 6:04
  • 1
    \$\begingroup\$ You're not supposed to close off parentheses on separate lines in a Lisp. For instance clojuredoc refers to the Scheme style guide when it comes to formatting and indentation, and the Scheme guide calls it unacceptable: Absolutely do *not* place closing brackets on their own lines. \$\endgroup\$ – daniero May 3 '15 at 17:16
14
\$\begingroup\$

1966 - Fortran 66

Fortran 66 is earlier version of Fortran programming language. It came in picture when American Standards Association proposed to develop an "American Standard Fortran". FORTRAN 66 effectively became the first "industry-standard" version of FORTRAN.

Disclaimer : I only have a compiler for Fortran 77. It has been tested on fort77 on Ubuntu and g77 on Windows 7. Just hoping nothing breaks on an actual Fortran 66 compiler!

Task 1

       PROGRAM HELLO
       WRITE (6,100)
C      FORMAT STATEMENTS AND HOLLERITH FORMAT WAS STANDARD FOR 1966
100    FORMAT(27HFORTRAN 66 WAS MADE IN 1966)
       END

Note that in 1966 we did not have strings or lower case.

Task 2

        PROGRAM ASCIIART
C NOTE WE DO NOT NEED TO DECLARE VARIABLES
C THE FIRST LETTER SAYS THE TYPE 
        WRITE (6,200) 
200     FORMAT(13HFIRST NUMBER?)
        READ (5,500) N
500     FORMAT(I7)
        CALL ASCII(N)
        END
        SUBROUTINE ASCII(N)
C  SOME IMPLEMENTATIONS COULD HANDLE DYNAMIC ARRAYS - LINE(N)
        DIMENSION LINE(72)
C  SPACES ARE IGNORED - SO NAMES CAN BE SPACED
        DATA LETTER N /1HN/, NO LETTER /1H /
          DO 100 I = 1,N
            DO 101 J = 1,N
                IF(J .EQ. 1 .OR. J .EQ. N .OR. I .EQ. J) GOTO 10
                    LINE(J) = NO LETTER
                GOTO 12
  10            LINE(J) = LETTER N
  12        CONTINUE
  101       CONTINUE
C          ALL I/O IS LINE ORIENTED
            WRITE (6,300) (LINE(K), K = 1,N) 
  300       FORMAT(72A1) 
  100     CONTINUE
        END

Although designed as a numerical language, lots of character processing can be done in FORTRAN 66. A good reference is: DAY, C.A. (1972) Fortran Techniques, with special reference to non-numerical applications, Cambridge University Press

Task 3

        PROGRAM GCD
C BUT WE CAN DECLARE TYPES IF WE WANT
        INTEGER U,V,VALUE
        WRITE (6,100)
100     FORMAT(13HFIRST NUMBER?)
        READ (5,500) U
500     FORMAT(I7)
        WRITE (6,200)
200     FORMAT(14HSECOND NUMBER?)
        READ (5,500) V
        CALL GCDBIN(VALUE, U, V)
        WRITE (6,300) VALUE
300     FORMAT(I8)
        END

        SUBROUTINE GCDBIN(VALUE, U, V)
        INTEGER VALUE
        INTEGER U, V
12      IF( U .EQ. V) GOTO 10
          IF( U .GT. V ) GOTO 11
              V = V-U
11        U = U-V
          GOTO 12
10      VALUE = U
        END

Just as a reminder. The reason the code looks like it does is determined by the input medium, the 80 column punched card:

An 80 Column Punched Card

\$\endgroup\$
13
\$\begingroup\$

2008 - Genie

Genie is a programming language having syntax inspired from python, D languages. It use vala compiler & libraries but with syntactical differences. See https://wiki.gnome.org/action/show/Projects/Genie

It uses indentation as block identifier like python. If you define [indent-{count-of-space}] on top of script, compiler check against spaces. If you omit this block, compiler still works but against tab character. So you need to use tab in that case.

Task 1

[indent=4]

init
    print "Genie was made in 2008"

Task 2

[indent=4]

def asciiart (n:int) : void
    for var i = 0 to n
        for var j = 0 to n
            if j == 0 || j == n || i == j
                stdout.printf ("N")
            else
                stdout.printf (" ")
        print "\r"

init
    asciiart(3)

Task 3

[indent=4]

def gcd (m:int, n:int) : int
    var large = 0
    var small = 0
    if m != n
        if m > n
            large = m
            small = n
        else
            large = n
            small = m
        while small != 0
            m = large % small
            large = small
            small = m
        return large
    return 0  

init
    gcd(8, 12)
\$\endgroup\$
  • 1
    \$\begingroup\$ What happens if you say [indent=4] but you actually indent by 2 spaces? Does it break? \$\endgroup\$ – Sp3000 Apr 9 '15 at 11:40
  • \$\begingroup\$ Genie is compiled language, So you first need to compiled it. If indentation is not followed accordingly program will not be compiled. So no run time break atleast I think. \$\endgroup\$ – kuldeep.kamboj Apr 9 '15 at 11:59
13
\$\begingroup\$

2009 - CoffeeScript

CoffeeScript began as a small project of jashkenas to learn how parsing does work. The first commit was on December 13, 2009 with the description "initial commit of the mystery language". On December 24, 2009, the first release, 0.1.0 was released. It was quite incomplete, and features were added in. 0.1.4 released a day after 0.1.0 changed assignment operator to = and fixed grammar quirks like a(1)(2)(3)(4) not working (PHP, take lessons). 0.1.5 added ranges.

0.2.0 (January 5, 2010) introduced the syntax that is more known today with significant whitespace. The syntax looked more like now.

0.5.0 (February 21, 2010) rewritten the compiler to be written in CoffeeScript. At this point, CoffeeScript got 300 hits on GitHub a day.

1.0.0 (December 24, 2010) the project was announced on Hacker News. The language was mostly stable at this point.

Task 1

console.log("CoffeeScript was made in 2009!")

Task 2

print_n: data =>
  n: Number(data)

  numbers: []

  i: 0
  while i < n
    numbers.push(i)
    i += 1.

  numbers.forEach(i =>
    give_shape: j =>
      if j is 0 or j is i or j is n - 1
        'N'
      else
        ' '..

    values: give_shape(j) for j in numbers.
    console.log(values.join('')).
  ).

process.stdin.resume()
process.stdin['on']('data', print_n)

Doesn't look anything like today's CoffeeScript, does it? Blocks ended with dots (no indentation rules), function call required parenthesis, => was used for all functions. Also, lots of features were missing. coffee-script (yes, a long name) was purely a compiler, it wasn't able to run code directly. Also, no range iteration syntax.

Task 3

gcd: a, b =>
  if b is 0
    a
  else
    gcd(b, a % b)..
\$\endgroup\$
  • \$\begingroup\$ Is it just me or this answer is out of time? @kuldeep.kamboj answered 7 hours ago with a language from 2008, and you answered with a 2009 language. \$\endgroup\$ – Ismael Miguel Apr 9 '15 at 18:37
  • \$\begingroup\$ @IsmaelMiguel: It is, but it's not disallowed to do it, you just cannot jump to earlier period that it is considered right now. I figured that first version of CoffeeScript would be interesting, so I did it. \$\endgroup\$ – Konrad Borowski Apr 9 '15 at 20:34
  • \$\begingroup\$ Yes, it is interesting. And reading the question, it doesn't say you can or can't jump backwards. I'll have to give you this one. \$\endgroup\$ – Ismael Miguel Apr 9 '15 at 20:46
13
\$\begingroup\$

1979 - AWK

AWK is a small programming language used by Unix wizards to process text files, optionally extracting data and computing some results. AWK was "originally written in 1977, and distributed with Version 7 Unix," but the latter was released in 1979, which is also where Wikipedia's timeine lists it.

Task 1

AWK programs are often one-liners typed into a shell, like so:

$ awk 'BEGIN { print "AWK was made in 1979!" }'
AWK was made in 1979!

Task 2

Of course, you can put a program in a large file.

function ascii_art(s) {
    result = "";
    for (i = 0; i < s; i++) {
        if (i > 0)
            result = result "\n";
        for (j = 0; j < s; j++) {
            if (i == j || j == 0 || j == (s - 1))
                letter = "N";
            else
                letter = " ";
            result = result letter;
        }
    }
    return result;
}

{ print ascii_art($1) }

And run it as:

$ awk -f ascii_art.awk
5
N   N
NN  N
N N N
N  NN
N   N

(That 5 is my input. AWK's "main" function always loops over all lines of input; I could've also passed in a file full of numbers.)

Interestingly, AWK has no real string concatenation operator: instead, you just write two string expressions next to each other, like result = result letter.

Task 3

This one's plain and simple:

awk '{ while ($2 > 0) { t = $1; $1 = $2; $2 = t % $2; } print $1 }'
30 20
10

Note how AWK has those $1, $2 variables that retrive the nth "word" in the line -- this really demonstrates its specfic roots in processing text files.

\$\endgroup\$
12
\$\begingroup\$

1994 - Racket

Is Racket a programming language, or is it a family of programming languages?

Task 1

#lang racket
(displayln "Racket was made in 1994!")

Task 2

#lang racket
(define (ascii-art-n n)
  (for ([i (range n)])
    (for ([j (range n)])
      (display
       (if (member j (list 0 i (sub1 n))) "N" " ")))
    (display "\n")))

Task 3

#lang racket
(define (my-gcd m n)
  (if (zero? n) m (my-gcd n (modulo m n))))

Racket has the built-in function gcd, so I use the name my-gcd.

\$\endgroup\$
  • \$\begingroup\$ Should it not be if (zero? n) in the gcd? \$\endgroup\$ – VisualMelon Apr 15 '15 at 7:34
  • 1
    \$\begingroup\$ Isn't Racket just one of the 30+ implementations of Scheme? As in, Racket : Scheme = GCC : C \$\endgroup\$ – Tobia Apr 20 '15 at 21:34
  • \$\begingroup\$ It started as PLT Scheme in 1994. I guess technically Racket is from 2010 as that's when they took that name. It's different enough from regular scheme to be a separate language (for instance things are immutable by default). \$\endgroup\$ – Harald Korneliussen Nov 29 '16 at 13:12
  • \$\begingroup\$ @Tobia, the "is it a different language" question tends to be a bit tricky for the extended Lisp family. Most of the syntax and a lot of the basic functions go way back. But Scheme feels very different from Lisp, and Racket feels pretty different from classic Scheme. I think this answer would be better if it showed off more distinctively rackety features. \$\endgroup\$ – dfeuer Mar 14 at 19:05
12
\$\begingroup\$

1975 - Microsoft BASIC

The original Microsoft BASIC interpreter was written by Bill Gates and Paul Allen for the Altair 8800, despite neither of them having access to one. It was a success, and was subsequently ported to a wide range of early personal computers, providing the programming language that most of a generation of programmers started with.

The programs here were tested on a Commodore 64 emulator (1977), but they should work on nearly any variant of Microsoft BASIC.

"Hello, World!" variant

Rather straightforward, does exactly what it says.

1 PRINT "MICROSOFT BASIC WAS MADE IN 1975"

PETSCII Art N

Nothing too fancy here; just a pair of loops to write out the "N". The code will work for any value of N up to about 32767, but the screens of the computers Microsoft BASIC ran on were rarely larger than 40x25, giving a practical limit of 22 (to prevent scrolling when the "READY." prompt appears after program completion).

1 INPUT N
2 FOR I = 1 TO N
3 FOR J = 1 TO N
4 IF I = J OR J = 1 OR J = N THEN PRINT "N";:GOTO 6
5 PRINT " ";
6 NEXT J
7 PRINT:NEXT I

GCD

Microsoft BASIC doesn't have an integer mod function, so I use the subtraction-based variant of Euclid's algorithm. This also demonstrates the lack of compound control structures and the abundant use of GOTOs that characterized the early dialects of BASIC.

1 INPUT A%,B%
2 IF A% = B% THEN GOTO 6
3 IF A% > B% THEN A% = A% - B%:GOTO 5
4 B% = B% - A%
5 GOTO 2
6 PRINT A%
\$\endgroup\$
  • 3
    \$\begingroup\$ ...hence the origin of the term "spaghetti code" with abundant use of GOTO in large programs. \$\endgroup\$ – mbomb007 Apr 22 '15 at 21:33
  • \$\begingroup\$ Hopefully you tried it on a PET emulator (PETs are from 1978 or thereabouts, 64s are a few years newer). The BASICs are (nearly) the same though (the first PET version did not have a GO token, to write GO TO, but allowed spaces in keywords everywhere). \$\endgroup\$ – Rhialto Jul 5 '17 at 19:37
12
\$\begingroup\$

2001 - C#

Language History

C# was developed by Microsoft for its .NET platform as part of the Common Language Infrastructure. It was later approved as a standard.

Then, in 2015, I posted this answer. Sampriti pointed out that it was made in 2000, not 2001, so I updated the answer. The edit broke everything. I changed it back to 2001 with Calvin's Hobbies' permission. So, to all reading this: C# was actually made in 2000. (Note that keeping it as 2001 does not give me an advantage in terms of score since the scoring system favors older languages.)

"Hello, World!" Variant

using System;
using System.IO;

class Program {
    public static void Main() {
        Console.WriteLine("C# was made in 2000!");
    }
}

ASCII Art N

using System;
using System.IO;
using System.Text;

class Program {
    public static void Main() {
        int N = Int32.Parse(Console.ReadLine());

        if (N == 1)
            Console.WriteLine("N");
        else
            AsciiN(N);
    }

    public static void AsciiN(int n) {
        string line;

        Console.WriteLine("N" + new string(' ', n-2) + "N");

        for (int i = 2; i < n; i++) {
             line = "N" + new string(' ', i-2) + "N" +
                 new string(' ', n-i-1) + "N";

             Console.WriteLine(line);
        }

        Console.WriteLine("N" + new string(' ', n-2) + "N");
    }
}

GCD

using System;
using System.IO;

class Program {
    public static void Main(string[] args) {
        int a = Convert.ToInt32(args[0]);
        int b = Convert.ToInt32(args[1]);

        Console.WriteLine(GCD(a, b));
    }

    public static int GCD(int a, int b) {
        return b == 0 ? a : GCD(b, a % b);
    }
}
\$\endgroup\$
  • 2
    \$\begingroup\$ According to Wikipedia, C# first appeared in 2000. \$\endgroup\$ – Zero Fiber Apr 12 '15 at 7:29
  • \$\begingroup\$ @SampritiPanda: Thanks. Changed it to 2000 and it broke everything, changed it back to 2001 with Calvin's permission but I'll add a note about it actually being 2000. \$\endgroup\$ – Alex A. Apr 12 '15 at 20:11
  • 1
    \$\begingroup\$ Why would 2000 break everything? Is Y2K still a problem today? \$\endgroup\$ – ASCIIThenANSI Apr 14 '15 at 2:38
  • \$\begingroup\$ @ASCIIThenANSI: The script that creates the leaderboard relies on answers being posted in a certain order. (Calvin's Hobbies could explain much better than I could.) Basically when I changed 2001 to 2000, the leaderboard listed this answer as well as every answer posted after it as invalid. To circumvent that, I and the others would have to delete and repost in order. So... it's staying 2001. \$\endgroup\$ – Alex A. Apr 14 '15 at 3:07
  • 2
    \$\begingroup\$ Too bad you're only allowed to use C# 1.0. Newer features really set C# apart. \$\endgroup\$ – Dennis_E Apr 29 '15 at 13:08
12
\$\begingroup\$

1985 - Dr. LOGO

Dr. LOGO splash-screen

Digital Research (DR) aimed to make programming accessible to children and one of its releases was Dr. LOGO for the Amstrad CPC range of home computers. In 1986 this became the third programming language I learnt, at the ripe old age of 10, the first two being CreatiVision BASIC on the Dick Smith Wizzard in 1982 when I was 6, and Locomotive BASIC also on the Amstrad in 1986. BASIC (or variants thereof) is still very widely used, so I have chosen Dr. LOGO because it is the first language I learnt that wasn't a version of BASIC! LOGO (originally developed in 1967) became famous for its use of turtle graphics, however, here I will be demonstrating that it is capable of far more than just that! I have no idea if these procedures would work on the original version of LOGO. I can only confirm that they work on the 1985 version of Dr. LOGO for the Amstrad.

The procedures:

Screen shot of LOGO procedures

to year
pr "Dr.\ LOGO\ was\ made\ in\ 1985!
end
to N :n
(local "count "item "line)
make "count 1
repeat :n [make "line " make "item 1 repeat :n [make "line lput (if or or :item = 1 :item = :n :item = :count ["N] ["\ ]) :line make "item :item + 1] pr :line make "count :count + 1]
end
to gcdr :x :y
op if :x = 0 [:y] [gcdr remainder :y :x :x]
end

Task 1

to year
pr "Dr.\ LOGO\ was\ made\ in\ 1985!
end

to starts the procedure, with the name of the procedure following it. pr simply means print. String literals are terminated by a space or certain other special characters, requiring a backslash before each printing space. end completes the procedure.

Task 1 output

Task 2

to N :n
(local "count "item "line)
make "count 1
repeat :n [
  make "line "
  make "item 1
  repeat :n [
    make "line lput (
      if or or :item = 1 :item = :n :item = :count
        ["N]
        ["\ ]
    ) :line
    make "item :item + 1
  ]
  pr :line
  make "count :count + 1
]
end

The :n in the procedure declaration means that it takes a parameter as input and stores it in n. local makes the following variables locally available only, so as not to pollute the global name space. The parentheses are required to stop local from trying to include the next primitive as part of its input. Dr. LOGO has no equivalent of a while loop, only a very simple version of for called repeat which repeats a fixed number of times. :n is used to get the value of the variable named n. repeat cannot contain newlines, so the indentation is for ease of reading only. make "line " stores an empty string in line. lput stands for last put, returning the first parameter appended to the second. The parentheses are not required around the if statement, they simply increase readability. The ors have been nested with the second or taking the first two parameters and the first or taking the result of the second or and the third parameter. If the expression is true, it returns N, if false, it returns , which is then appended to line via lput. As is common with most early languages, there is no increment operator, so I have to simply add 1 to the variable. After the inner loop has completed, it prints the contents of line and automatically appends a newline.

Task 2 output

As a bonus, it can also output even sized patterns!

Task 2 bonus output

Task 3

to gcdr :x :y
op if :x = 0 [:y] [gcdr remainder :y :x :x]
end

My original procedure was called gcd, but it wasn't recursive, so I wrote a new one, which is why there is an r in the name. This procedure takes two parameters, :x and :y. op is to output the result, the equivalent of return in a lot of modern languages. It very simply checks to see if x is zero, and if it is, the answer must be y. If not, it calculates the remainder (modulus) of y divided by x, which it passes as the first parameter of the recursive function and x (which we know to be non-zero) as the second parameter. Dr. LOGO automatically prints the output when it returns to the prompt.

Task 3 output

I hope you had as much fun looking at the procedures and screen-shots as I did completing this challenge! It was a nostalgic trip down memory lane for me. A combination of RAM and ROM, it's more volatile than I hoped but I'm glad the bus still goes there!

\$\endgroup\$
  • 3
    \$\begingroup\$ I don't know why, but I love this language. It's something about that old-timey screen that makes me want to go buy a 1980s computer and start coding. \$\endgroup\$ – ASCIIThenANSI May 3 '15 at 4:33
  • 2
    \$\begingroup\$ I used WinApe to get the screenshots. It's a nice Amstrad emulator that fairly faithfully captures the look and feel of the Amstrad CPC range of computers. The crisp solid colours (no banding like some other emulators use) and slight blurring where two colours meet are just like the original analogue screen! There is also a deliberate imperfection on the left edge of the image! \$\endgroup\$ – CJ Dennis May 5 '15 at 5:07
11
\$\begingroup\$

2012 - Picat

Picat is a simple, and yet powerful, logic-based multi-paradigm programming language aimed for general-purpose applications. It integrates Logic Programming, Functional programming, scripting, Constraint programming, and Dynamic programming with tabling. It was introduced in 2012.

You can download the compilers here, unfortunately, there is no way to Try Online.

You can find some really cool uses of Picat here

Task 1

main =>
  writef("Picat was made in 2012!")

Task 2

main =>
  N = read_int(),
  foreach(I in 1..N)
    writef("N"),
    if(I == 1 || I == N) then
      foreach(J in 1..(N - 2))
        writef(" ")
      end,
      if(N > 1) then
        writef("N")
      end
    else
      foreach(J in (1..(I - 2)))
        writef(" ")
      end,
      writef("N"),
      foreach(J in (1..(N - 1 - I)))
        writef(" ")
      end,
      writef("N")
    end,
    writef("%n")
  end.

Task 3

gcd(A, 0) = A.
gcd(A, B) = gcd(B, A mod B).

main =>
  A = read_int(),
  B = read_int(),
  writef("%d%n", gcd(A, B))
\$\endgroup\$
11
\$\begingroup\$

2000 - D

The D programming language is an object-oriented, imperative, multi-paradigm system programming language created by Walter Bright and Andrei Alexandrescu.

It's syntax is very similar to C++ as it originated as a re-engineering of C++, but it has redesigned some core features of C++ and has taken ideas from Java, Python, Ruby, C# and Eiffel.

To try out D online, visit this D compiler + Pastebin.

Task 1

import std.stdio;

void main() {
   writeln("D was made in 2000!");
}

Task 2

import std.stdio;

void main() {
    int n; readf("%s", &n);

    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
            if(j == 0 || j == i || j == (n - 1)) write("N");
            else write(" ");
        }
        writef("\n");
    }
}

Task 3

import std.stdio;

int gcd(int a, int b) pure {
    if(b == 0) return a;
    return gcd(b, a % b);
}

void main() {
    int a, b; readf("%s %s", &a, &b);

    gcd(a, b).writeln;
}
\$\endgroup\$
11
\$\begingroup\$

2001 - Joy

Joy is a purely functional programming language created by Manfred von Thun. Unlike other functional programming languages, Joy is based on composition of functions rather than lambda calculus. It's also a stack-based languages.

Task 1

"Joy was made in 2001!\n" putchars .

"Joy was made in 2001!\n" pushes the string to the stack. Then putchars prints the string. The period at the end terminates the program.

Task 2

DEFINE
    asciin ==
        1 swap dup
        [ null not ]
        [ dupd swap
          [ null not ]
          [ stack rest 3 take [ in ] unary
            [ "N" putchars ] [ " " putchars ] branch
            pred ]
          while
        pop pred "\n" putchars ]
        while
        3 [ pop ] times .

Example:

3 asciin .
N N
NNN
N N

Task 3

DEFINE
    gcd == [null] [pop] [dup rollup rem] tailrec .

Example:

8 12 gcd .
4

Joy has a bunch of built-in functions with the suffix rec. They are recursive combinators. For example, tailrec helps us define anonymous functions with tail recursion.

In this program, [null] checks whether the top of the stack is 0. If it is true, it will pop it from the stack, then the new top of the stack is the answer. Otherwise, it will executes [dup rollup rem] (if the stack is [Y X] it will become [X%Y Y]), then recursively call itself. So it's just the Euclidean algorithm.

\$\endgroup\$
  • 1
    \$\begingroup\$ J is based on function composition. It can even solve things like obverses (usually inverse) of functions. \$\endgroup\$ – seequ Apr 12 '15 at 18:20
  • \$\begingroup\$ @Sieg It's already 1990. You can write a J answer now. \$\endgroup\$ – alephalpha Apr 15 '15 at 2:25
11
\$\begingroup\$

1995 - JavaScript

We all know all about JS already, let's just cut to the chase. No? All right.

JS the the language for the web. It's been supported by the major browsers practically since its inception.

JavaScript is like Java the way a car is like a carpet. Sure, they're both transportation vehicles, but the similarity ends around there.

JS has uses outside of the web too. Most prominent is Node.JS. The JS core is actually pretty simple - objects, functions, regex, arrays, keywords, etc. It's then built up -- DOM functions in browsers; filesystem, command line, and HTTP modules for Node. Some might say that the [Canvas / AJAX / Speech Synthesis] API is its own extension as well.

In addition to core extensions (which are built in by the interpreter), there are innumerable plugins as well. Some notable ones include jQuery, jQuery, and moar jQuery.

That's enough for now. Let's get to the challenges!

Task #1 - "Hello, World!" Variant

document.write("JavaScript was made in 1995!");

This is really bad form, but it's still valid. document.write() writes to the DOM.

Task #2 - ASCII Art N

function N(n){
    var l = [], i, j;
    for (i=0; i<n; i++){
        l[i] = ["N"];
        for(j=1; j<n; j++){
            l[i][j] = j == i || j == n-1 ? "N" : " ";
        }
        l[i] = l[i].join('');
    }
    return l.join('\n');
}
alert(N(prompt("n?")));

Pretty straightforward. Create a function, use a couple loops, and create an array with Ns, then join the arrays. The last line will use an alert() after a prompt(). alert() does output; prompt() does input. Call our function between that.

Task #3 - GCD

function GCD(a,b){
    return b==0 ? a : GCD(b, a % b);
}

Simple Euclidian algorithm. Uses a recursive function. Note that this only creates a function; it doesn't use it anywhere.

\$\endgroup\$
  • 1
    \$\begingroup\$ +1 for "JavaScript is like Java the way a car is like a carpet." \$\endgroup\$ – Amos M. Carpenter May 5 '15 at 5:44
  • 1
    \$\begingroup\$ @AmosM.Carpenter Thanks, but i don't think the vote went through. ;) And i can't claim originality on the statement. I first saw it on What's the difference between JavaScript and Java? on SO, but it apparently predates that. \$\endgroup\$ – Scimonster May 5 '15 at 6:16
  • \$\begingroup\$ Strange... how about now? Reloaded and up-voted again. Might be because I just created the codegolf account to post an answer. Heh, had a look at that question on SO - rare that a pure tongue-in-cheek answer gets to many more upvotes than a serious one. :-) \$\endgroup\$ – Amos M. Carpenter May 5 '15 at 6:26
  • \$\begingroup\$ Worked now. When that happens to me it's usually because of an internet connectivity issue. \$\endgroup\$ – Scimonster May 5 '15 at 6:29
11
\$\begingroup\$

1993 - R

R is the aptly-named descendant of S. It was designed with statistics and scientific computing in mind.

Task 1

cat("R was made in 1993!")

Task 2

ascii <- function(n){
    if(n==1){
        cat("N")
        }else{
            a <- matrix(c("N",rep(" ",n-2),"N"),byrow=TRUE, ncol=n, nrow=n)
            diag(a) <- "N"
            cat(apply(a,1,paste,collapse=""),sep="\n")
            }
}

This little implementation showcases some of R neat tricks, such as vector recycling (in the fifth line) and the apply function family (in the seventh line). Indents are only for readability.

Usage:

> ascii(10)
N        N
NN       N
N N      N
N  N     N
N   N    N
N    N   N
N     N  N
N      N N
N       NN
N        N
> ascii(3)
N N
NNN
N N
> ascii(1)
N

Task 3

gcd <- function(m,n){
    q <- 1:max(m,n)
    max(q[!m%%q & !n%%q])
    }

This somewhat golfed implementation use the fact that the modulo operator %% is vectorized in R, allowing us to compute this without any loop.

Usage:

> gcd(8,12)
[1] 4
> gcd(12,8)
[1] 4
> gcd(3,30)
[1] 3
> gcd(5689,2)
[1] 1
> gcd(234,876)
[1] 6
\$\endgroup\$
  • 2
    \$\begingroup\$ Nice, +1! I especially like the matrix solution for the ASCII N. To make things a little prettier you could also add <!-- language-all: lang-r --> somewhere in the post to invoke syntax highlighting. ;) \$\endgroup\$ – Alex A. Apr 14 '15 at 15:44
  • \$\begingroup\$ @AlexA. True I always forget (despite the fact that I campaigned to have r syntax highlighting on SE :) ) \$\endgroup\$ – plannapus Apr 15 '15 at 6:01
  • \$\begingroup\$ You're behind that magic? Thank you, I use it all the time! \$\endgroup\$ – Alex A. Apr 15 '15 at 14:21
11
\$\begingroup\$

1972 - Smalltalk

A historical programming language question without Smalltalk? Inconceivable!

It's the mother of all OO languages, it's the source of Patterns, Agile, XP, and has influenced (and still influences) languages like Java and many others. The Eclipse IDE was born as a Java-reincarnation of Smalltalk's RefactoringBrowser, for instance, and things like message chaining have made their way to Java as well (though Java is still waiting for proper closures). Although it's become something of a niche language these days, I still love to dabble in it when I get the chance. Debugging in any other language I've seen pales in comparison, and (I know several Java people who hate it when I say this) I don't know of any other language in which one is nearly as productive as in Smalltalk.

Smalltalk is completely OO in the sense that everything is an object. No primitives, even numbers are objects, and even nil is an Object that understands messages. Syntax is, simply, object message, which always returns an object so that another message can be sent to the result. There are only 5 reserved keywords (self, super, true, false, nil) in most flavours, the rest of the language is written in itself. It is all about elegance and readability, and is strong on conventions for explicit naming, with the goal that code reads almost like English and can be (mostly) understood by anyone without having to know details about the language.

Smalltalk began in 1972, and several flavours of it have developed over the years. Its decline is probably due to a time in which most serious alternatives were all commercial. Pharo is a newer, open source flavour of Smalltalk (based on Squeak) for anyone who wants to give it a try.

Task 1

The default output in Smalltalk is called the Transcript. Asking it to show some text is very simple.

Code:

Transcript show: 'Smalltalk was made in 1972!'

Explanation: Here, Transcript is the class (also an object, of course), which understands the message #show:. Colons introduce arguments, and the argument we pass is the string we want to show; single quotes convert text to a String instance.

Task 2

Code:

| isNBlock oddNumbers |
isNBlock := [:rowIndex :columnIndex :size |
    columnIndex = 1 or: [columnIndex = size or: [columnIndex = rowIndex]]].
oddNumbers := #(1 3 5 7).
oddNumbers do: [ :eachOddNumber |
    Transcript show: ('Output for n=', eachOddNumber asString); show: Character cr.
    1 to: eachOddNumber do: [ :eachRowIndex |
        1 to: eachOddNumber do: [ :eachColumnIndex |
            Transcript show: ((isNBlock value: eachRowIndex value: eachColumnIndex value: eachOddNumber)
                ifTrue: [ 'N' ]
                ifFalse: [ ' ' ])
            ].
        Transcript show: Character cr.
        ].
    Transcript show: Character cr.
    ].

Explanation: The first line declares two local variables (scope here just being the workspace for the sake of testing), which are then defined as a block of code (a closure) that, given three arguments, returns whether or not the character to print should be an N, and some odd numbers, respectively. Then, we simply iterate over the numbers (loop variables are, by convention, prefixed with each to emphasise their iterative nature), and over the rows and columns. For each row and column index, we pass both the indexes and the size to the three-argument block and show the appropriate character in the transcript. The rest is just to make sure we show a Character cr, i.e. a carriage return (yes, sometimes even Smalltalk uses abbreviations, I'm not a fan of them) at the right times.

Selecting the code in the workspace and executing a "do it" from the context menu produces the following output in the transcript:

Output for n=1
N

Output for n=3
N N
NNN
N N

Output for n=5
N   N
NN  N
N N N
N  NN
N   N

Output for n=7
N     N
NN    N
N N   N
N  N  N
N   N N
N    NN
N     N

A possible improvement would be to have the block return the character instead of a boolean, but I thought it might be clearer this way.

Task 3

Code:

firstNumber gcd: secondNumber

Explanation: An Integer instance understands the message #gcd: and is able to find the greatest common divisor of itself and the argument. So if you selected the text 6132 gcd: 1679 (in a workspace, or in any other text area) and selected "print it" from the context menu, it would print 73.

\$\endgroup\$
  • \$\begingroup\$ Note that I've deliberately chosen to do this Smalltalk-style, i.e. using explicit naming, rather than golfing my code, since, according to the rules, golfing is not required (and wouldn't really be appropriate in Smalltalk). However, if anyone's interested in seeing some great one-liners (though some are wrapped & indented for readability) that show off what you can do with very few built-in message sends and yet remain very readable, take a look at this elegant pharo code post. \$\endgroup\$ – Amos M. Carpenter May 5 '15 at 9:26
  • \$\begingroup\$ “Mother of all OO languages” **cough** \$\endgroup\$ – ceased to turn counterclockwis May 5 '15 at 17:57
  • 1
    \$\begingroup\$ @leftaroundabout: Haha... where there's a mother, there's gotta be a grandmother, too, right? (Even if it's one the kids can never quite remember.) True, Simula came even earlier than (and influenced) Smalltalk, and may have introduced the concept of "objects", but the term "object-oriented programming" was introduced by Smalltalk, and - correct me if I'm wrong - I believe Simula wasn't 100% OO like Smalltalk. \$\endgroup\$ – Amos M. Carpenter May 5 '15 at 23:55
10
\$\begingroup\$

2003 - Scala

Scala is a modern multi-paradigm programming language designed to express common programming patterns in a concise, elegant, and type-safe way. Scala has been created by Martin Odersky and he released the first version in 2003.

Hello world

println("Scala was made in 2003!");

ASCII

def ASCII(N: Int) = for(i <- 0 to N-1) {
  var s = ("N" + " "*(N-2) + "N").toCharArray; 
  s(i) = 'N';
  println(s.mkString)
}

GCD

def gcd(a: Int, b: Int): Int = if(b == 0) a else gcd(b, a % b)
\$\endgroup\$
10
\$\begingroup\$

1983 - Turbo Pascal

I remember playing with this around 88, however that's about all I remember about it, so the following may have some syntax errors.
The wikipedia page can describe it better than I can. I liked the paragraph about the speed of it confounding Bill Gates.

Task 1

program hiThere;
begin
  WriteLn('Turbo Pascal was made in 1983!');
end.

Task 2

program bigN;
var
    n   : Integer;
    i   : Integer;
    c   : Integer;
begin
    Write('Size of N : ');
    ReadLn(n);
    if n = 1 then
        WriteLn('N')
    else
    begin
        for i := 1 to n do
        begin       
            Write('N');
            for c := 2 to n do
            begin
                if c = n then
                    WriteLn('N');
                else
                begin
                    if c = i then
                        Write('N')
                    else
                        Write(' ');
                end;
            end;
        end;
    end;
end.

Task 3

program GCD;
var
    a    : Integer;
    b    : Integer;
    x    : Integer;
    gcd  : Integer;
begin
    Write('First integer : ');
    ReadLn(a);
    Write('Second integer : ');
    ReadLn(b);
    while a > 0 do
    begin
        x := b;
        b := a;
        a := x mod a;
    end;
    Write('GCD is ');
    WriteLn(b);
end.
\$\endgroup\$
10
\$\begingroup\$

1980 - Ada

In the 1970s, the United Stated Department of Defense had a problem: their IT was often done ad-hoc, and used hodgepodge of many different programming languages, many of them specific to the hardware they were used on, and none of them designed for military use. The DoD decided it was time for standardisation, and one language was to be designed, which could do everything from the payroll to the nuclear weapons. It was to be designed for safety, in such a manner that the compiler could catch as many programming mistakes as possible. On the other hand, it was also targeted at embedded systems (such as the aforementioned nukes). Committees were formed, years passed, and in 1980 was born MIL-STD-1815, otherwise known as Ada.

Thus, the type system is strict enough to make Pascal look like machine code, there are run-time checks for everything, and the syntax uses mainly English words, to catch typos. It was also one of the first languages to include exception handling, and one of the first languages to explicitly support concurrency in the syntax. The compiler could even catch potential deadlocks.

Unsurprisingly, it ended up with the safety of a battle tank, the reliability of a battle tank, but also the speed of a battle tank and the aesthetics of a battle tank. 1980-s era computers could barely run it, and it would take until 1987 for the language to gain some use - and even then it was only because the military mandated it. Compilers are large and difficult to write, and take long to run because of all the checks they do.

Today, its drawbacks have been lessened by powerful hardware, and its emphasis on safety still stands. It sees use mainly in fields where safety is very important and software bugs could have disastrous consequences. Aside from the military, it is used in such things as air traffic control systems, railway transport, spaceflight, and sometimes banking.

Task 1

with Ada.Text_IO;
use Ada.Text_IO;
procedure Task1 is
begin
   Put_Line("Ada was made in 1980!");
end Task1;

Task 2

with Ada.Text_IO, Ada.Integer_Text_IO;

procedure AsciiN is

   procedure N(n:integer) is
   begin
      for y in 1..n loop
         for x in 1..n loop
            if x=1 or x=y or x=n then
               Ada.Text_IO.Put('N');
            else
               Ada.Text_IO.Put(' ');
            end if;
         end loop;
         Ada.Text_IO.New_Line;
      end loop;
   end N;

   number : integer;
begin
   Ada.Integer_Text_IO.Get(number);
   N(number);
end AsciiN;

Task 3

with Ada.Integer_Text_IO;
use Ada.Integer_Text_IO;

procedure GCDProgram is
   function gcd( a:integer; b:integer ) return integer is
   begin
      if b = 0 then
         return a;
      else
         return gcd(b, a mod b);
      end if;
   end gcd;

   a, b : integer;
begin
   Get(a);
   Get(b);
   Put(gcd(a, b));
end GCDProgram;
\$\endgroup\$
  • \$\begingroup\$ IMO, the æsthetics of Ada are in fact surprisingly elegant, given the language's origin. Better than Fortran, COBOL or Java at any rate... \$\endgroup\$ – ceased to turn counterclockwis Apr 17 '15 at 20:56
  • 1
    \$\begingroup\$ @leftaroundabout: A battle tank isn't the ugliest thing in the world either, in the grand scale of things. The point is more that the syntax was designed specifically to prevent mistakes, and that elegance was sacrificed when necessary. I'd say Java is actually more elegant (if not a whole lot). COBOL is actually from the DoD as well, 21 years earlier, so they did improve. \$\endgroup\$ – marinus Apr 17 '15 at 22:10
  • \$\begingroup\$ The date of Ada 83 Reference Manual is January 1983 (not 1980). \$\endgroup\$ – scaaahu Nov 8 '15 at 13:08
10
\$\begingroup\$

1985 - Miranda

(I actually wrote this earlier but forgot to post it. It is a landmark, however, and I think it deserves to be included.)

Miranda is the precursor to Haskell. It was the first purely functional language to be commercially supported (and not merely an academic endeavour). As such, it tried to have proper I/O and the like.

Miranda is a lot less sophisticated than Haskell, though. For one, monads had not been invented yet, so input would involve a lazily constructed list from a given input source (i.e $- is the list of characters on stdin, $+ is the list of values of expressions in the input); output would involve an expression evaluating to a list of system messages, which would be obeyed in order as they become available. This had the problem, of course, that the result of a function application like read "foo" is not referentially transparent, because foo might have changed.

Thus, a Miranda script simply contains one expression to be evaluated (which would evaluate to a list of system messages), followed optionally by a list of definitions used in the expression. (All of mine just evaluate to a single Stdout message).

It is worth noting, given the syntax, that Haskell did not start as an extension to Miranda, it is just heavily inspired by it.

Task 1

#! /usr/bin/mira -exp
[Stdout "Miranda was made in 1985!\n"]

Task 2

#! /usr/bin/mira -exp
[Stdout (buildN (hd $+))]

buildN :: num->[char]
buildN n = lay [[fill n x y | x<-[1..n]] | y <- [1..n]]

|| note the academically inspired 'if' and 'or'
fill n x y = 'N', if x=y \/ x=1 \/ x=n
           = ' ', otherwise

Task 3

#! /usr/bin/mira -exp
[Stdout (show (uncurry gcd (take 2 $+)))]

|| uncurry isn't in the standard library
uncurry :: (* -> * -> **) -> [*] -> **
uncurry fn [a,b] = fn a b

|| this gcd function is taken directly from the documentation
gcd :: num -> num -> num
gcd a b = gcd (a-b) b, if a>b
        = gcd a (b-a), if a<b
        = a,           if a=b
\$\endgroup\$
10
\$\begingroup\$

1972 - SQL

The Wikipedia timeline of languages has this as being 1972, however I can't find any other references to support this.
Given the untimely demise of Raymond Boyce in 1974 and his gaining of a PhD in computer science in 1971, 1972 seems to fit.

SQL (Structured Query Language) is designed for managing data held in a relational database. It was originally called SEQUEL, but was later changed to SQL because of trademark issues.

It was originally developed by Donald Chamberlain and Raymond Boyce to work with IBMs database management system, System R.

SQL became a ANSI standard in 1986 and since then has gone through a number of revisions. Even though it is a standard, there are many different variations/implementations of it. This means that portability of code between different RDBMSs can sometimes be difficult.

SQL is comprised of DML (Data Manipulation Language) and DDL (Data Definition Language).

DML consists of statements like SELECT, UPDATE, INSERT, etc and is the language used to query, modify, remove the data in the RDBMS.

DDL consists of statements like CREATE, ALTER, DROP, etc and is the language used to define the data structures in the RDBMS.

While I've used T-SQL to complete the tasks I've tried to complete the tasks with mostly standard SQL. The queries should also be able to port to other and earlier dialects of SQL relatively easily.

Task 1

As a simple query that returns a literal.

SELECT 'SQL was made in 1972!' AS Greeting

Another way that demonstrates some basic SQL

-- Create a table for the greetings
CREATE TABLE Salutation (
    Type VARCHAR(10) NOT NULL PRIMARY KEY,
    Greeting VARCHAR(100) NOT NULL
    );

-- Put some rows into the table
INSERT INTO Salutation (Type, Greeting)
VALUES 
    ('ALL','Hello World!')
    ,('MADE','SQL was made in 1972!')
    ,('DIRECT','Nice to meet you!')
    ,('AUSSIE','G''Day Mate!')
    ,('COWBOY','Howdy Partner!')
    ,('GOLFED','Hi!');

-- Select the greeting that we want
SELECT Greeting
FROM Salutation
WHERE Type = 'MADE';

Task 2

This query makes use of a Number (or Tally) table to provide a way of doing pseudo loops. Normally I would use the STUFF function to do the string manipulation, but this isn't that compatible with other dialects.

This does rely on the correct interpretation of NULLs however and the SPACE function returning NULL for negative values.

--Create a table of numbers
CREATE TABLE Number (
    N INTEGER NOT NULL PRIMARY KEY
    );
INSERT INTO Number (N)
SELECT TOP 100000  
    ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) N
FROM master.sys.columns a, master.sys.columns b;

-- Do an ASCII N
-- Oracle being one of the first implementers of SQL would use bind
-- variables, eg :N.  The functions used would also be different
-- For example ISNULL would likely require a DECODE and NVL function. 
DECLARE @N INTEGER = 5 

SELECT
    'N' + ISNULL(SPACE(N-2)+'N','') + ISNULL(SPACE(@N-N-1)+'N','') S
FROM Number
WHERE N <= @N;

Result from the query

S
------------
N   N
NN  N
N N N
N  NN
N   N

Task 3

Using the same Number table as created in Task 2.

DECLARE @A INTEGER = 284
DECLARE @B INTEGER = 876

-- This query uses a CASE statement.  In earlier versions of Oracle SQL
-- a DECODE function would have been used instead.  The MOD function
-- would be used rather than the % operator
SELECT @A A, @B B, MAX(N)
FROM (
    SELECT N, @A % N AM, @B % N BM
    FROM Number
    WHERE N <= CASE WHEN @A < @B THEN @A ELSE @B END
    ) AS GCD
WHERE AM = 0 AND BM = 0;

The result of the query is

A           B           GCD
----------- ----------- -----------
234         876         6
\$\endgroup\$
  • \$\begingroup\$ @AlexA. Yes I have used the T-SQL dialect, especially with the CREATE FUNCTION. However I have tried to keep the queries inside the functions to one's that could be done with earlier versions of SQL. The functions that I have used inside the queries themselves should be able to be replaced with equivalents depending on the dialects. For example, the case statement could be replace with DECODE (Oracle), ISNULL with a NVL construct. I think I will change the example so they are just queries. \$\endgroup\$ – MickyT Apr 30 '15 at 1:15
  • 2
    \$\begingroup\$ Kudos for a very odd choice! However, your Aussie greeting should be spelt G'day mate!. And it should be AUSSIE as very few of us are related to Mr. Osbourne! \$\endgroup\$ – CJ Dennis May 2 '15 at 11:44
  • 1
    \$\begingroup\$ @CJDennis Have change the greeting. I wouldn't want to offend our mates downunder :) \$\endgroup\$ – MickyT May 2 '15 at 20:18
10
\$\begingroup\$

1969 - B

B is the language developed at Bell Labs by Thompson and Ritchie for the Unix operating system project. It is the original curly-brace language, and one of the first to include a notion that programs should be portable from system to system. Many of the original Unix utilities (such as dc) were first written in B as well. B eventually transitioned smoothly into C (you'll notice that the language in marinus's answer is much closer to B than it is to modern C), but the language we see at the start of the process is clearly a different one, lacking support for types, global declarations, for loops, and many other basic C features.

examples run with this compiler

Task 1

main() {
  puts("B was made in 1969!");
}

Of course, there was no C standard library to link against in 1969, so really we need to define a string printing function too:

main() {
  printstring("B was made in 1969!");
}

printstring(s) {
  extrn terminator;
  auto c, i;
  i = 0;
  while((c = char(s, i++)) != terminator) putchar(c);
  putchar('*n');
}

terminator '*0';

putchar was present in B's standard library from the beginning. Notice that special character codes are escaped with *, not with \ as they would be in C. (The string terminator was '*e' - 0x03 - on the original system, but that won't work with a modern system, so we're using '*0'.) Indexing a string is done with the built-in char function, because B was designed with the expectation that pointers indexed whole 36-bit words, and characters (four to a word) would have to be extracted manually.

Notice also that the order we define functions and variables doesn't matter. Unlike C, B simply doesn't have a notion of a global scope: if you want to use a name as a variable, you need to declare it manually within your function with extrn. Undeclared names are just assumed to be valid functions.

Interestingly it seems (?) that with the lack of floats or structs, the otherwise-unused . character was a valid "letter" and could be used in variable names. So we could probably have called the function string.print to help with project organization.

Task 2

N(size) {
  auto x, y;
  y = size;
  while (y) {
    x = size;
    while (x) {
      if (x == y | x == 1 | x == size) putchar('N'); else putchar(' ');
      x--;
    }
    putchar('*n');
    y--;
  }
}

B doesn't support the && or || operators, but depending on the version, it might detect that & or | are used inside a conditional statement and short-circuit them anyway.

Local variables couldn't be initialized on creation, but required a separate statement. (The optional syntax auto x 10 actually declared x to be an array, not to initialize it with a value.)

Task 3

gcd(a, b) {
  return (b == 0 ? a : gcd(b, a % b));
}

This is where B really shone: it was designed from the outset to support recursive evaluation, making mathematical expressions very easy to write compared to some languages of the time (recursion wasn't universal yet; Fortran wouldn't get it for a while). The ternary operator also helped with this, and was present from the start.

Notice that return requires the value to be parenthesized, like in the bc language.

\$\endgroup\$
  • \$\begingroup\$ It's funny how they put auto back in C++11. \$\endgroup\$ – marinus May 7 '15 at 13:06
  • 1
    \$\begingroup\$ @marinus auto never left - it's still in C for the same purpose as B (it's just useless, since the type name does the same job). C++ just found a new use for it. \$\endgroup\$ – Leushenko May 7 '15 at 13:17
  • \$\begingroup\$ Huh. Didn't know that. \$\endgroup\$ – marinus May 7 '15 at 13:33
  • 1
    \$\begingroup\$ Note that the YBC compiler speaks a different dialect of B than the original Bell Labs language. I don't think any of the differences show up in the examples here. \$\endgroup\$ – Mark May 8 '15 at 0:58
10
\$\begingroup\$

1968 - Refal

Finally, a programming language from the Soviet Union.

Refal is a language made by Valentin Turchin in 1968. It is based on pattern matching, and oriented toward symbol manipulation.

The implementation I used here is Refal-5. It might be very different from the first implementation.

Task 1

$ENTRY Go { = <Prout 'Refal was made in 1968!'>; }

Task 2

$ENTRY Go { = <Prout <Ascii-N <Numb <Card>>>>; } 

Ascii-N { 1   = 'N';
          2   = 'NN\nNN';
          s.n = <Next-N <Ascii-N <- s.n 1>>>; }

Next-N { e.1 'N\n' e.2 = e.1 ' N\n' <Next-N e.2>;
         e.1 'N'       = e.1 'NN\n' e.1 ' N'; } 

Task 3

$ENTRY Go { = <Prout <GCD <Numb <Card>> <Numb <Card>>>>; } 

GCD { s.1 0   = s.1;
      s.1 s.2 = <GCD s.2 <Mod s.1 s.2>>; }
\$\endgroup\$
  • 2
    \$\begingroup\$ PSA for all the language designers out there : Prout is an onomatopoeia for farts in french language. \$\endgroup\$ – Aaron Oct 26 '15 at 16:13
10
\$\begingroup\$

1963 - CPL

CPL was a language developed jointly between Cambridge and London Universities as an alternative to Algol 60. The CPL can be considered Combined Programming Language, Cambridge Programming Language or Cambridge Plus London depending on your perspective. It may be possible to, in time, to execute the programs on an original working compiler via the Atlas Emulators being developed, but I suspect not.

CPL is significant because it led to the development of the more efficient BCPL at Cambridge and hence to C.

The main references sources for the language are the Computer Journal Article from 1963, the entry in Progopedia and Wikipedia.

You may find my notation slightly different to that in the examples in Propedia and Wikipedia. I've adhered more carefully to that described in 1963 and I think some of the other examples may be incorrect or a result of changes made during compiler implementation.

Task 1

Write [‘CPL was made in 1963’]
Newline

Task 2

index n = 0, j = 0, i = 0
Read [n]
for i = step 1, 1, n
     § for j step 1, 1, n
         § test ( j ≡ 1 ) ∨ ( j ≡ I ) ∨ ( j ≡ n)
             then do
                 Write [‘N’]
             or do
                 Space
         §
         Newline
     §

Task 3

rec function Gcd [integer a,b] = result of
     §
     test b ≡ 0
         then do result := a
         or do test a ≡ 0
             then do result := b
             or do result := Gcd [b, a - b]
     §

dec § integer i, j
     Read [i, j]
     Write [ Gcd [ i,j ] ]
     Newline
     §

\$\endgroup\$
  • \$\begingroup\$ BTW: I also have the three tasks written in BCPL which ought to be included in such a history tour, but the 5 year rule would not permit it! \$\endgroup\$ – Brian Tompsett - 汤莱恩 Sep 1 '15 at 21:57
9
\$\begingroup\$

2006 - PowerShell

PowerShell is a scripting and administration language that runs on top of the .NET framework, and duly has access to all the libraries we know and love, and uses a pipe-line to get everything done. I really don't know much about PowerShell, maybe someone who does can fill in the History for me, but I believe there are a number of people who don't like that a whole swathe of commands start with hyphens ("-"), I can't say I care all that much.

As is so often the case in these weird scripting languages, PowerShell uses the dollar symbol to denote variables. In PowerShell, a line-feed and a semi-colon are (as far as I am aware) synonymous.

All of the following was tested with PowerShell version 1, I think, I'm not sure what the -version flag does when calling PowerShell.

Task 1

echo "PowerShell was made in 2006!"

Echo is an alias for Write-Output is how to output stuff in PowerShell, I'm not sure I quite understand it.

Task 2

There are two types of "loop" here, the for loop of $i from 1 to $n, and a "foreach-object" filter (aliased as "%") over a seqence from 1 to $n.

function N()
{
    # the param construct lets you do all sorts of weird things
    param($n = 5)

    for($i = 1; $i -le $n; $i++)
    {
        echo ((1..$n | % {if ($_ -eq 1 -or $_ -eq $n -or $_ -eq $i) {"N"} else {" "}}) -join '')
    }
}

You can call the function with a parameter or just as it is, and it will use the default of 5. These all produce the same result.

N
N 5
N -n 5
$i=5;N $i
N(2+3)

See how we can also explicitly name the parameter (with the -n flag), and that the parenthesis are just contain an expression, and are not used for function calls.

By sticking this same code in a file on it's own, removing the function { and closing } bits, you can create a PowerShell script file which you call with the . command, and can be passed arguments just like a function.

. N.ps1 7
. N.ps1 -n 11

Task 3

Below is a simple recursive gcd using the Euclidean algorithm as suggested. Note that the return is effectively optional, and is omitted before the recursive call. return yields a value and exits, without it you can continue to output stuff (but we do not do this here so it doesn't matter). Also note the short-hand for parameters in function calls (would need a param clause to make this into a runnable script file).

function gcd($a, $b)
{
    if ($b -eq 0)
    {
        return $a
    }
    else
    {
        gcd $b ($a % $b)
    }
}

I am always surprised that % is mod, and not -mod.

\$\endgroup\$
9
\$\begingroup\$

2002 - Io

Io is a dynamic prototype-based language. It's designed to be simple, powerful and practical. It was first released in 2002 by Steve Decorte.

Task 1:

"Io was made in 2002!" println

Task 2:

task2 := method(n,
    text := ""
    for(i, 0, n-1, 
      text = ""
      for(j, 0, n-1, 
        (i==j or j==0 or j==n-1) ifTrue(text = text .. "N") ifFalse(text = text .. " ")
      )
      writeln(text)
    )
)

A very naïve approach, I'll improve it later.

Task 3:

task3 := method(g,q, (q==0) ifTrue(writeln(g)) ifFalse(task3(q, g%q)))
\$\endgroup\$
9
\$\begingroup\$

1995 - Ruby

Ruby was introduced 20 years ago by Yukihiro "Matz" Matsumoto. Ruby was mainly influenced by Perl, Smalltalk, Eiffel, Ada and Lisp.

According to its website, Ruby is a dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write, which very true since well-written Ruby reads a lot like English.

It is a good choice for someone's first programming language.

Ruby has a extensive library of gems. It is very popular for the Ruby on Rails framework which many modern websites are built upon.

Task 1 - Hello World Variant

puts "Ruby was made in 1995!"

Task 2 - Ascii Art

n = gets.to_i
ascii_art = n.times.map do |i|
    n.times.map do |j|
        (j == 0 || j == i || j == (n - 1)) ? "N" : " "
    end.join
end.join("\n")
puts ascii_art

Task 3 - GCD

def gcd(a, b)
    b.zero? ? a : gcd(b, a % b)
end

puts gcd(*gets.split.map(&:to_i))

Pretty simple implementation of GCD. The last line might be a confusing but what it's basically doing is getting a line of input, splitting it into two integers and passing that as the argument to the gcd function.

You can also use lambdas for a shorter implementation:

gcd = ->(a, b) { b.zero? ? a : gcd.(b, a % b) }

gcd.(27, 36)
\$\endgroup\$
  • \$\begingroup\$ GCD Was task 3 and N was task 2 \$\endgroup\$ – Optimizer Apr 14 '15 at 12:15
  • \$\begingroup\$ Putting <!-- language-all: lang-rb --> will invoke syntax highlighting for the code bits. \$\endgroup\$ – Alex A. Apr 21 '15 at 15:15
9
\$\begingroup\$

1993 - Batch

My reason for suggesting that Batch was created in 1993 is explained in a question I posted at StackOverflow: https://stackoverflow.com/questions/29484750/when-was-batch-created

Hello World.bat

@echo off
echo Batch was created in 1993!
pause

I added the pause at the end with the assumption that it would be run by 'double-clicking' the file in explorer, as opposed to called from the command line (otherwise the CMD window would instantly close when the script has completed). My other two scripts assume they are being called from the command line, as they both require input from stdin.

ASCII N.bat

@echo off
setLocal enableDelayedExpansion

for /l %%a in (1,1,%1) do (
    set "l="
    for /l %%b in (1,1,%1) do (
        set "c= "
        if %%b==1 set c=N
        if %%b==%1 set c=N
        if %%b==%%a set c=N
        set l=!l!!c!
    )
    echo !l!
)

This script uses the fact that the crossing character (that is, the line that travels diagonally from top left to bottom right in the character N) is always populated at position y in the row - where y is the current column (if %%b==%%a set c=N). Then the first and last character in each row is always populated. The first for loop defines rows, and the inner for loop defines columns.

GCD.bat

@echo off
setLocal enableDelayedExpansion

for %%a in (%1, %2) do (
    set "l%%a="
    for /l %%b in (1,1,%%a) do (
        set /a a=%%a %% %%b
        if !a!==0 set l%%a=!l%%a! %%b
    )
)

for %%c in (!l%1!) do for %%d in (!l%2!) do if %%c==%%d set h=%%c

echo !h!

When doing anything even remotely complicated in Batch, there always tends to be a lot of nested for loops. The first set of loops creates two lists which contain every number from 1 to n which divides evenly into the n, where n is either of the inputted values. The second loops just compare each value in one list to each value in the other, until the highest value that exists in both lists is found. Just a note that Batch doesn't actually have arrays, so all I have done is created a bunch of variables with uniform names.

Hacker Aesthetic

\$\endgroup\$
  • 3
    \$\begingroup\$ Some people's batch skills amaze me. \$\endgroup\$ – kirbyfan64sos Apr 16 '15 at 1:53
  • \$\begingroup\$ @kirbyfan64sos Nice of you to say :) \$\endgroup\$ – unclemeat Apr 16 '15 at 3:28
9
\$\begingroup\$

1981 - C++

Can't believe someone put Turbo Pascal and not C++!

Everyone knows about C++, right? It's one of my favorite programming languages due to its speed and expressiveness (yes, it's expressive; template metaprogramming counts!).

Note that I originally used 1983 as the creation date, but then I ended up with an invalid answer. Besides, C with Classes was created in 1981, and that's what C++ was before it was renamed.

These examples were made based on what I know about the first version of C++ when it was actually called C++ and the headers included with cfront.

Task 1

#include <iostream.h>

int main() {
    cout << "C++ was made in 1983!\n";
    return 0;
}

Task 2

#include <iostream.h>

void ascii(int n) {
    for (int i=0; i<n; ++i) {
        for (int j=0; j<n; ++j)
            if (j == 0 || j == i || j == n-1)
                cout << 'N';
            else cout << ' ';
            // I could also have written that as:
            // cout << (j == 0 || j == i || j == n-1 ? 'N' : ' ');
        cout << '\n';
    }
}

int main() {
    int n;
    cin >> n;
    ascii(n);
}

Task 3

#include <iostream.h>

int gcd(int a, int b) {
    return b ? gcd(b, a%b) : a;
}

int main() {
    int a, b;
    cin >> a >> b;
    cout << gcd(a, b) << '\n';
}

I still can't get over the fact that cfront had a graph library and a path library that (for some reason) were removed in the standardized version of C++.

\$\endgroup\$
  • 1
    \$\begingroup\$ You already answered for 1986 (Oberon), making this answer show up as invalid in the OP's code snippet table (although it's superfluous, and I personally think it's nice to have for good measure... just letting you know.) \$\endgroup\$ – Lynn Apr 17 '15 at 16:52
  • 1
    \$\begingroup\$ @nooodl Darn, I think I'll change this to 1981 for C for Classes and say it was the first version... ;) \$\endgroup\$ – kirbyfan64sos Apr 17 '15 at 17:25
  • 1
    \$\begingroup\$ I'm pretty sure the std namespace was not anywhere to be seen in 1981 C++ code. There's already a C++98 submission – we should somehow make the version difference meaningful. For instance, you could keep this in the “C with classes” spirit by using putchar and the like, but include some features of the C++ language itself. \$\endgroup\$ – ceased to turn counterclockwis Apr 17 '15 at 19:35
  • \$\begingroup\$ @leftaroundabout Fixed. I based it on the examples from cfront in 1983. \$\endgroup\$ – kirbyfan64sos Apr 17 '15 at 20:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.