# Programming Languages Through The Years

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.

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.

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.

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

• 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

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.

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> • This should help. – swish Apr 6 '15 at 9:10 • Wikipedia has a list for everything: this one for non-esoteric languages by year. – Sanchises Apr 6 '15 at 12:30 • 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. – CJ Dennis May 3 '15 at 2:51 • I feel like making a second account just to get us past 1971. – marinus May 5 '15 at 10:49 • 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! – Brian Tompsett - 汤莱恩 May 19 '15 at 18:19 ## 98 Answers # 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. • Some people's batch skills amaze me. – kirbyfan64sos Apr 16 '15 at 1:53 • @kirbyfan64sos Nice of you to say :) – unclemeat Apr 16 '15 at 3:28 # 1984 - Standard ML Standard ML is a descendant of the ML programming language. It's a functional programming language with strong, compile-time type checking and inference. I work with Haskell a lot, and comparing it to that, Standard ML seems less pure, and definitely lacks a lot of the nice syntactic sugar that Haskell has. Nonetheless, the type system looks neat, and code written in it looks elegant. (I, too, learned this language just to answer the challenge, and because I've been interested in older functional languages like ML and Miranda. If you're a Standard ML expert, and notice something in this code looks really unidiomatic, feel free to point it out.) ## Task 1 print "Standard ML was made in 1984!\n";  The print function prints the given string to standard output. Not much to say here. ## Task 2 fun asciiArt (s : int) : string = let fun line n = implode (List.tabulate (s, fn i => if i = 0 orelse i = n orelse i = s - 1 then #"N" else #" " )) in String.concatWith "\n" (List.tabulate (s, line)) end; fun readInt h = Option.valOf (TextIO.scanStream (Int.scan StringCvt.DEC) h); print "Size: "; val s = readInt TextIO.stdIn; print (asciiArt s);  To get some asciiArt of size s, we define a helper function that gets us the nth line, then generate a bunch of lines and concatenate them with newlines. We read a number from TextIO.stdIn and print the corresponding ASCII art N. The List.tabulate function is basically: tabulate (n, f) = [f 0, f 1, ... f (n-1)]. ## Task 3 fun gcd (a : int) (b : int) : int = if b = 0 then a else gcd b (a mod b); fun readInt h = Option.valOf (TextIO.scanStream (Int.scan StringCvt.DEC) h); print "First number: "; val a = readInt TextIO.stdIn; print "Second number: "; val b = readInt TextIO.stdIn; print ("The GCD of " ^ Int.toString a ^ " and " ^ Int.toString b ^ " is " ^ Int.toString (gcd a b) ^ ".\n");  We implement the Euclidean GCD algorithm recursively, read two numbers, and print the result. There's no built-in GCD function, it seems. ^ is an interesting choice of string concatenation operator. • I think your gcd fails to show off SML's powerful module system. The same algorithm should work in any Euclidean domain. You can write a GCD functor that takes the domain structure as an argument. – dfeuer Mar 14 '19 at 19:17 • @dfeuer I encourage you to post your own answer. – Lynn Mar 14 '19 at 20:52 # 1975 - Scheme Scheme is one of the older and most successful dialects of the LISP family of languages. It predates Common Lisp, Emacs Lisp, and most others still in use. Its philosophy is based on minimalism and extensibility. The basic language is made of a minimal set of syntax rules; 12 "fundamental forms," or keywords that need to be specifically implemented by the runtime, such as if and define; and 11 "library forms," keywords that are part of the language definition, but can be internally implemented using the fundamendal forms. The minimalism is coupled with extreme extensibility. Scheme's macro system is arguably the most advanced hygienic, Turing-complete pre-processor of all programming languages. It is to C's macro preprocessor as a Ferrari is to a soap box! Scheme's unique philosophy and its hacker-friendly minimal footprint have always attracted many thinkers and tinkerers alike. 40 years after its inception we have dozens of implementations, running on all sorts of platforms and using all manner of compiler or interpreter technologies, including very bizarre but effective ones. Scheme is an excellent testbed for programming language ideas, but it is also a great language for everyday programming. Its syntax may appear strange to those unfamiliar with LISP, but it has many advantages, starting with its regularity. Every function, operator, and control structure of the language takes the same form: (name arguments...) where both the name and the arguments may be nested expressions. This simplicity and regularity makes Scheme the ideal language for teaching programming to novice students, as demonstrated by the success of Structure and Interpretation of Computer Programs by MIT Press. Citing Wikipedia: Before SICP, the introductory courses were almost always filled with learning the details of some programming language, while SICP focuses on finding general patterns from specific problems and building software tools that embody each pattern. ### Hello World! (begin (display "Scheme was made in 1975!") (newline))  ### ASCII Art N (let ((n (read))) (let row ((r 1)) (let col ((c 1)) (display (if (memq c (list 1 n r)) "N" " ")) (if (< c n) (col (+ c 1)) (newline))) (if (< r n) (row (+ r 1)))))  ### GCD (let gcd ((m (read)) (n (read))) (if (zero? n) m (gcd n (modulo m n))))  # 1995 - Java # History Java is a general-purpose language that runs on a large variety of systems, from web servers to smart phones and disc players. Development started in 1991 at Sun Microsystems, version 1.0 was released in 95. In 99, version 1.2 was renamed to "Java 2". Java is very verbose and thus unsuitable for code golfing, which hasn't stopped some from trying. It also has a reputation for yielding over-engineered solutions and being generally clumsy. Basically, just like this text. # Hello World class M{public static void main(String[]a){System.out.print("Java was made in 1995");}}  (golfed as much as possible) # ASCII N public class Main { public static void main (String[] args) { int n = Integer.parseInt(args[0]); for (int i = 0; i < n; i++) { System.out.print('N'); for (int j = 1; j < n-1; j++) { System.out.print(j == i ? 'N' : ' '); } System.out.println('N'); } } }  # GCD public class Main { public static void main (String[] args) { int a = Integer.parseInt(args[0]); int b = Integer.parseInt(args[1]); System.out.printf("GCD of %d and %d: %d%n", a, b, gcd(a, b)); } public static int gcd(int a, int b) { if (b > a) return gcd(b, a); else if (b == 0) return a; else if (a == 0) return b; else return gcd(b, a%b); } }  • +1 for applying Java coding style to the history paragraph ;) – DLosc Apr 15 '15 at 19:23 • I would still use % instead of - in the last gcd call. – Paŭlo Ebermann Apr 17 '15 at 20:59 • "golfed as much as possible", lol. no. Remove the space after String[], and change println to print. – mbomb007 Apr 21 '15 at 15:45 • fixed, also renamed args to a – Cephalopod Apr 22 '15 at 18:49 # 1997 - Fortran 95 I am a bit late with this answer, since Fortran 95 wasn't published until 1997. Oh well. From Wikipedia: Fortran 95, published officially as ISO/IEC 1539-1:1997, was a minor revision, mostly to resolve some outstanding issues from the Fortran 90 standard. Nevertheless, Fortran 95 also added a number of extensions, notably from the High Performance Fortran specification. ### “Hello, World!” program say_my_name print '(A)', "The Fortran 95 standard was published in ... 1997." end program say_my_name  ### ASCII art “N” For the ASCII art task, Fortran's formatted i/o is actually quite handy: program paint_N integer :: N, i character(len=500) :: fmt read*, N do i=1,N write(fmt, "('(', 2(A, ',', 'T', I0, ','), A, ')')") & "'N'", i, "'N'", N, "'N'" print fmt end do end program paint_N  ### Greatest common divisor For the GCD task I chose the binary method. The bitwise intrinsics (IAND, IOR, ISHFT), as well as user-defined pure functions, were only introduced with Fortran 95. Also, I took the liberty of adding a loop so you can compute more than one GCD per execution. The algorithm is a straightforward translation of http://en.wikipedia.org/wiki/Binary_GCD_algorithm#Iterative_version_in_C. program binary_GCD_algorithm integer :: a, b do read(*,*, END=1) a, b print*, gcd(a,b) end do 1 continue contains pure integer function gcd(a, b) integer, intent(in) :: a, b integer :: shift, u, v, t u = a v = b if (u == 0) then gcd = v else if (v == 0) then gcd = u else shift = 0 find_shift: do while (iand(ior(u, v), 1) == 0) u = ishft(u, -1) v = ishft(v, -1) shift = shift+1 end do find_shift halve_u: do while (iand(u, 1) == 0) u = ishft(u, -1) end do halve_u reduce_v: do halve_v: do while (iand(v, 1) == 0) v = ishft(v, -1) end do halve_v swap: if (u > v) then t = v v = u u = t end if swap v = v - u if (v == 0) exit reduce_v end do reduce_v gcd = ishft(u, shift) end if end function gcd end program binary_GCD_algorithm  • Just in case you missed the note, posting versions of programming languages is discouraged unless the version is significantly different than its predecessors. I see that your code in your Fortran 90 answer does offer different task solutions, which is good, but I'm no Fortran expert and can't say how much it's really worth having both versions. I'd say to refrain from posting any more Fortran versions until the original Fortran. – Calvin's Hobbies Apr 16 '15 at 23:40 • @Calvin'sHobbies Not to worry, I won't be tackling any older versions, and I don't know what the 2003/2008 versions would have to add. It is sometimes difficult to say what is a “different language”, and I would argue that at least Fortran pre-90 (fixed format) and post-90 are “different”, but not really 90 and 95, I admit. If you prefer, I can delete one of the answers. Neither of them are needed for the chain. – xebtl Apr 17 '15 at 11:42 • To be honest, after seeing a “C++98” answer, I thought Fortran 95 should qualify as well, and the year was about right. Then I realized that 90/95 could actually make difference for the GCD task. – xebtl Apr 17 '15 at 11:43 # 1995 - PHP PHP began life as a project of Rasmus Lerdorf, intended to help him manage his personal homepage. The original name was Personal Home Page Tools, later changed to Personal Home Page/Forms Interpreter (PHP/FI). Lerdorf never intended to create a programming language, but things snowballed, a development team was formed, and the rest is history. PHP is now used extensively for server-side scripting as one of the options for the P in LAMP (or WAMP); more-recent versions have added support for command-line and client-side GUI applications as well. Syntax is closest to Perl, with $ used for variables and implicit casting between strings and numbers. Like JavaScript, PHP has been criticized for its ad-hoc construction, which resulted in numerous weird quirks and inconsistencies; nevertheless, I find it fairly easy to work with in practice. The PHP language reference is always helpful.

<?php echo "PHP/FI was made in 1995!" ?>


(The name was changed to the recursive acronym "PHP: Hypertext Preprocessor" in 1997.)

<?php
$size =$HTTP_GET_VARS['size'];
for($i = 0;$i < $size;$i++) {
for($j = 0;$j < $size;$j++) {
if($j ==$i || $j == 0 ||$j == $size - 1) { echo 'N'; } else { echo '&nbsp;'; } } echo '<br>'; } ?>  Since CLI support was not in the original PHP, it seemed appropriate to write these examples as web pages with input from URL parameters. I understand that $HTTP_GET_VARS used to be the way to do that; however, it is now deprecated in favor of $_GET, which is what I used to test my code (on PHP 5.5). The result looks best if you wrap the PHP in a <pre> tag. ### Task 3 <?php$a = $HTTP_GET_VARS['a'];$b = $HTTP_GET_VARS['b']; while($a > 0) {
$tmp =$b;
$b =$a;
$a =$tmp % $a; } echo$b;
?>


Putting all three in the same file (and changing $HTTP_GET_VARS to $_GET as mentioned above) gives the following result:

• Point of pedantry: the first version was actually called "PHP Tools" (for "Personal Home Page Tools"); "PHP/FI" was the name at the time of 2.0, just before it got rewritten into something recognisable. See php.net/history.php It would be interesting to get some old versions from the museum and try to write the code in those (the syntax is very different!) – IMSoP Apr 19 '15 at 18:24
• @IMSoP Point taken--I will add a note. Re: older versions, I almost downloaded one, but decided it wasn't worth the trouble of (re)configuring a web server to run it. – DLosc Apr 20 '15 at 15:07
• You missed an opportunity to do the screenshot in a 1995 browser :) – user61264 Nov 29 '16 at 12:55

# 1990 - J

'J was made in 1990!'


This reflects the typical use of J: in an REPL, this would echo the string back at you. Not very useful in general, but exactly what we want here.

' N' {~ (1) 0 _1}"1 =@i.


What we do here might be a bit different other languages would do. We start by creating an identy matrix of a given size: =@i.. Then we set the first and last collumn to be 1: (1) 0 _1}"1. (If you were to name everything, one might name it as 1 (first, last) set collumns, or something like that). Then, we use these values as indices to the string ' N', 0-indexed, so that we get the wanted result. Again, as this returns a string(matrix), this is printed to screen.

This is an anonymous function, so we could assign it to a variable (or not, but it is convenient), and run it:

    f =: ' N' {~ (1) 0 _1}"1 =@i.
f 5
N   N
NN  N
N N N
N  NN
N   N


There is just a builtin function for this: +.. However, since this is not fun in the slightest, we are going to define our own function:

<./&.:(_ q: ])


This also reflects the different attitude that is often used in J, as opposed to Von-Neumann languages. First, we aquire a table of all prime exponents of the entire list of numbers: (_ q: ]). Then, we find the minimum of every collumn: <./. Lastly, &.: applies the inverse of (_ q: ]) to the result, which gives the GCD.

# 1974 - CLU

CLU was created at MIT by Barbara Liskov. It's never widely used, but it influenced many important languages.

The development of CLU began in 1974, and the first version was released in 1975. But we need a language for 1974.

I've never used CLU, and I can't find a compiler for linux or windows, so I didn't test my code. Feel free to edit my post if you find anything wrong.

start_up = proc ()
po: stream := stream$primary_output () stream$putl (po, "CLU was made in 1974!")
end start_up


ascii_art_n = proc (n: int)
po: stream := stream$primary_output () for i: int in int$from_to (1, n) do
for j: int in int$from_to (1, n) do if j = 1 | j = i | j = n then stream$putc (po, 'N')
else stream$putc (po, ' ') end end stream$putc (po, '\n')
end
end ascii_art_n


CLU supports multiple assignment, which is known as parallel assignment in nowaday languages.

gcd = proc (m, n: int) returns (int)
while n > 0 do
m, n := n, (m // n)
end
return (m)
end gcd

• It looks like it's Python's granddad. – marinus Apr 25 '15 at 9:13
• Try clu2c. – kirbyfan64sos Apr 25 '15 at 22:18
• Nevermind; link's down. Oh well. +1 because you seriously saved all our hinds from 1974! – kirbyfan64sos Apr 26 '15 at 0:53
• Actually, there's a working version here...but the build system's badly broken. – kirbyfan64sos Apr 26 '15 at 1:01

# 1971 - dc

Thanks to marinus for recommending dc -- this is a little RPN calculator released with Unix V1 in 1971.

[dc was made in 1971!
]P


[] are string delimiters; apparently you can just include a raw newline in a string! It gets pushed to the stack, P prints it.

# Replace top of stack with string N.
[sv[N]]sN

# Line loop
[[ ]
LxdSx 1     =N
LxdSx ls    =N
LxdSx LydSy =N P
Lx 1- dSx 0<F]sF

# Ascii art loop
[ls Sx lFx 10P
Ly 1- dSy 0<G]sG

? dss Sy lGx


My eyes! dc has no good looping construct, but we can assign some code in a string to a register, say F, and then call it recursively based on some condition, e.g. =F.

We build up two looping 'subroutines' of this form -- F and G -- that run some code repeatedly, decrementing the number in some register until it hits zero. Then we use these registers (x and y -- LxdSx peeks a register value) to decide whether we want to print a space or an N.

There doesn't seem to be a pop command -- sv pops the top of stack and stores it in a 'junk' register, v.

## Task 3 (GCD, from wikipedia)

??[dSarLa%d0<a]dsax+p


This is Euclid's algorithm, implemented with the same approach to loops.

# 1970 - Forth

Try it here

Forth is a relatively easy-to-learn imperative and stack-based programming language. Forth was created by Charles Moore and Elizabeth Rather from a system that had been in development by Charles Moore starting in 1968. They improved and ported Forth to multiple systems over the next decade.

Forth was originally titled "FOURTH", but file names were limited to five characters on the IBM 1130 operating system, so it was named "FORTH".

Forth is written in "reverse Polish notation," which is also known as "postfix" notation. The language is extensible, meaning the user can define their own commands (called "words"), as shown below. Historically, all words would be uppercase, though now this is not a requirement.

I define a word called year that prints the string. The space after ." is required, but will not be printed.

: year ." Forth was made in 1970!" ;


I define a word called printn that prints the ascii 'N' as required. I also extended the functionality to allow even numbers as well, so that any integer greater than zero can be entered. (It displays nicely only up to about 90 or so using the given link.) Note that the indentation is purely for readability, though it can be typed and run this way as well.

: printn
dup 2 > if
dup 0 do
." N" dup 1- 1 do
I J = if ." N"
else space
then
loop
." N" cr
loop
else
dup 2 = if ." NN" cr ." NN" cr
else ." N" cr
then
then
drop ;


I define a simple word gcd that returns the greatest common divisor of two integers on the stack.

: gcd begin ?dup while swap over mod repeat ;


Run all three tasks with carriage returns (new lines) between their outputs like this:

year cr cr
5 printn cr
18 12 gcd .

• Hmph. Yesterday I learned that weird language just to get this challenge going again, only to find out it was actually the wrong year (1970, not 71) so I deleted my answer to wait until someone would eventually post 1971. Now I come back, and there you are, also with a Forth submission! If I'd known people would so be queueing up (or should I say, stacking up) for Forth... – ceased to turn counterclockwis May 7 '15 at 1:25
• @leftaroundabout I posted in the comments one week ago that I was going to do Forth for 1970. I've had my answer coded since a week before that, waiting to be posted at the right time. Also, I can't see your deleted answer, obviously. codegolf.stackexchange.com/questions/48476/… – mbomb007 May 7 '15 at 15:38
• @leftaroundabout Plus, it's not that weird, and if you'd even looked at the wikipedia article or the timeline ahead of time (or my comment), you would have known it was 1970. – mbomb007 May 7 '15 at 15:42
• Gee. Normally I read every single comment floating around a question with 50+ answers, how could I miss yours. Also, I never ever post comments that include some sarcasm to go with a mediocre joke about some particular language's characteristics. – ceased to turn counterclockwis May 7 '15 at 15:48
• @leftaroundabout Well, I read it as an upset-sounding comment. – mbomb007 May 7 '15 at 15:51

# 1972 - MUSL

In 1972 Manchester University first commissioned their MU5 computer system. The operating system for that computer was called MUSS (Manchester University Software System) and the language MUSL (Manchester University Systems Language) was created to implement that software.

The MUSL language inherited features from Atlas Autocode, Algol 68, Pascal, BCPL and was specifically designed for the implementation of portable operating systems. It was interesting to note that this development took place at the same time as C was being developed for unix. The MUSL compiler was developed using a parser generator called SYNTAB, used an intermediate code generator called MUTL (Manchester University Target Language) and a portable virtual machine code called MUBL (Manchester University Binary Language). MUTL was basically a JIT compiler as we would see it today. Several language compilers targeted MUTL including Fortran, Cobol, Algol, Pascal and so on.

The MUSL compiler was interesting to work with as it only had about 8 error messages. It just flagged "Lexical", "Syntax", "Semantics", "Type" and left it to the programmer to work out where the fault lay!

Although MUSL programs could be written in the normal source form, they were generally expressed in a tool called FLOCODER which graphically represented the code and permitted more than one concrete representation of the algorithm to enable implementation in multiple languages or on multiple platforms from the same file, including embedded documentation. The example MUSL programs are therefore expressed in both the orthodox manner as a code listing and also illustrated in FLOCODER formats, which is how they would have been prepared.

There are MU5 emulators being developed which may eventually run a MUSS system, but at present the code cannot be executed. MUSS (and hence MUSL) was not just implemented on the MU5 but was available on PDP11, VAX, ICL1900, Computervision CDS-4000 CAD/CAM system, MC68000 and several others besides. There may be one of these still running in a museum somewhere!

A brief bibliography:

• Ibbett, R.N. & Capon, P.C. (1978) "The Development of the MU5 Computer System", Communications of the ACM, pp 13-24.
• Morris, D & Ibbett, R.N. (1979) "The MU5 Computer System" The Macmillan Press.
• Ibbett, R.N. (1999) "The University of Manchester MU5 Project" IEEE Annals of the History of Computing, Vol. 21, No1, pp 24-33.
• Barringer, H., Capon, P.C. & Phillips, R. (1979) "The Portable compiling systems of MUSS", Software Practice and Experience, Vol 9, No.8, pp.645-655.

The MUSL:

MODULE HELLO
:: THE I/O LIBRARY BELONGS TO MUSS - NOT MUSL
:: THE FOLLOWING NOTATION GENERATES A POINTER TO A BYTE VECTOR
CAPTION(%"MUSL WAS MADE IN 1972$L"); *END  As a FLOCODER file: @TITLE HELLO @COL 1S-2R-3F @FLOW 1-2-3 @BOX 1.0 A Hello World Program in MUSL @BOX 1.1 MODULE HELLO @BOX 2.0 We call the MUSS CAPTION function with a pointer to a constant byte array containing the newline character @BOX 2.1 CAPTION(%"MUSL WAS MADE IN 1972$L");
@BOX 3.0
and exit
@BOX 3.1
*END
@END


As seen:

In MUSL:

MODULE ASCII
:: IN MUSL ALL TYPES MUST ALSO BE SIZED
INTEGER32 N, I, J;
IN.I() => N;
FOR I <> N DO
FOR J <> N DO
IF J = 1 ! J = I ! J = N THEN
OUT.CH("N");  :: AGAIN I/O IS MUSS
ELSE
OUT.CH(" ");
FI
OD
NEW.LINES(1);
OD
*END


In FLOCODER source:

@TITLE ASCII
@COL 1S-2R-3R-4R-5R-6T-7R-9R-10R-11R-12F
@COL 8R
@ROW 7-8
@FLOW 1-2-3-4-5-6FALSE-7-9-10-11-12
@FLOW 6TRUE-8-9
@BOX 1.0
Program to write ASCII Art
@BOX 1.1
MODULE ASCII
@BOX 2.0
Declare some 32 bit integers.
There is no default size for
arithmetic types
@BOX 2.1
INTEGER32 N, I, J;
@BOX 3.0
Use MUSS library IN.I
@BOX 3.1
IN.I() => N;
@BOX 4.0
Iterate for N Rows
@BOX 4.1
FOR I <> N DO
@BOX 5.0
Iterate for N Columns
@BOX 5.1
FOR J <> N DO
@BOX 6.0
Test if First, middle or last column
@BOX 6.1
IF J = 0 ! J = I ! J = N-1
@BOX 8.0
Output a letter N
using MUSS library OUT.CH
@BOX 8.1
OUT.CH("N");
@BOX 7.0
Output a space
using MUSS library OUT.CH
@BOX 7.1
OUT.CH(" ");
@BOX 9.0
End of Column loop
@BOX 9.1
OD
@BOX 10.0
Output end of line
using MUSS library NEW.LINES
@BOX 10.1
NEW.LINES(1);
@BOX 11.0
End of Row loop
@BOX 11.1
OD
@BOX 12.0
All done
@BOX 12.1
*END


As seen:

In MUSL form:

MODULE GCDEX
PSPEC GCD(INTEGER32, INTEGER32)/INTEGER32;
PROC GCD (A, B);
IF A = 0 THEN B => GCD; EXIT FI;
IF B = 0 THEN A => GCD; EXIT FI;
GCD (B, A - B) => GCD;
END ;
:: I/O FROM MUSS LIBRARY
OUT.I ( GCD ( IN.I(), IN.I() ), 0 ) ;
*END


In FLOCODER file format:

@TITLE GCD
@COL 1S-2R-3R-4T-6T-8R-9R-10R-11F
@COL 7
@COL 5
@ROW 4-5
@ROW 6-7
@FLOW 1-2-3-4FALSE-6FALSE-8-9-10-11
@FLOW 4TRUE-5-9
@FLOW 6TRUE-7-9
@BOX 1.0
Program to calculate
Greatest Common Divisor
Using Euclidean Algorithm
@BOX 1.1
MODULE GCDEX
@BOX 2.0
Specify procedure with
two arguments returning an int
@BOX 2.1
PSPEC GCD(INTEGER32, INTEGER32)/INTEGER32;
@BOX 3.0
Procedure is GCD with args A & B
@BOX 3.1
PROC GCD (A, B);
@BOX 4.0
Test if A is zero
@BOX 4.1
IF A = 0
@BOX 5.0
Return B
@BOX 5.1
B => GCD;
@BOX 6.0
Test if B is zero
@BOX 6.1
IF B = 0
@BOX 7.0
Return A
@BOX 7.1
A => GCD;
@BOX 8.0
Recursively call GCD
with B and the difference of A and B
and return the result
@BOX 8.1
GCD (B, A - B) => GCD;
@BOX 9.0
End of GCD function
@BOX 9.1
END ;
@BOX 10.0
Main Body code:
Input two integers using MUSS Library
IN.I, invoke GCD. Print the result using
MUSS library OUT.I in minimum digits.
@BOX 10.1
OUT.I ( GCD ( IN.I(), IN.I() ), 0 ) ;
@BOX 11.0
All done
@BOX 11.1
*END


As Seen:

† The MUSL code is handwritten, not the code that Flocoder would have generated; that was a bit uglier!

# 2005 - F#

F# (pronounced eff sharp) is a strongly typed, multi-paradigm programming language that encompasses functional, imperative, and object-oriented programming techniques. F# is most often used as a cross-platform CLI language, but can also be used to generate JavaScript and GPU code. Wikipedia

printfn "F# was made in 2005!"


let n = int32( System.Console.ReadLine() )
for y in 1..n do
for x in 1..n do
if x = 1 || x = y || x = n then
printf "N"
else
printf " "
printfn ""


# Explanation:

x = 0 || x = y || x = n


takes care for printing only vertical ( left and right | ) and diagonal ( \ )

simple implementation of Euclidean_algorithm

let a = int32( System.Console.ReadLine() )
let b = int32( System.Console.ReadLine() )

let gcd a b =
let mutable _a = a
let mutable _b = b
while _b <> 0 do
let c = _a % _b
_a <- _b
_b <- c
_a

printfn "%d" ( gcd a b )


gcd can be also written using tail recursion. Thanks to VisualMelon

let rec gcd a b =
if b = 0 then
a
else
gcd b (a % b)

• The task does seem to be after a recurisve gcd (and mutability isn't very F#y), let rec gcd a b = if b = 0 then a else gcd b (a % b) fits the bill – VisualMelon Apr 10 '15 at 12:06
• I prefer to use iterative solutions over recursive, due to stack overflow when deep recursions. but yes in this case it could be better. – wasikuss Apr 10 '15 at 12:37
• However, the F# compiler is Tail Recursive, which means the recursive call to gcd doesn't create a deeper stack frame, because the state of the current frame doesn't need to be preserved (the value is returned straight to caller), so it will won't overflow the stack. – VisualMelon Apr 10 '15 at 12:43
• @VisualMelon, I've never heard about Tail Recursion, good to know :) – wasikuss Apr 10 '15 at 13:04
• Your Task2 solution appears to be off slightly, it is effectively running n+1 rather than n; you can fix this by replacing all the 0s with 1s. – VisualMelon Apr 10 '15 at 13:20

# 2004 - Axo

"Just another" Befunge-inspired language, but hey, it's from 2004, at least it's not a Brainfuck clone, and the interpreter is still available.

>0                          !
%"Axo was created in 2004!$"! >[#!\ !( !  The other tasks also contain this output routine. An oddity about Axo is that it has a string mode (") and a raw mode ('). In string mode, $ pushes a newline instead of a literal $. The output routine is simply: [# "if top of stack is not zero" ( "output character". ### Task 2: >0" ?n">[#!! !( !} %:0 ! %:+1; ("$"<
>[;-#!\
>0.>[,-#!^
>;,-  #!'N'%
%      !
>,    #!'N'%
%      !
>[,-1-#!'N'%
>' '%
^.+1,(          <


This program uses the registers (; and ,) as X and Y counters. The value for n is kept on the stack. Apart from that it's just two nested loops, nothing fancy.

>0" ?a">[#!!
!( !}
%:         !
>0" ?b">[#!!
!( !}
%.         !
@
$year = "1987"; print "$language was made in $year!\n"; }  ## Task 2 sub task2 { my$N = @_[0];
for (my $row=1;$row <= $N;$row++) {
for (my $col=1;$col <= $N;$col++) {
if ($col == 1 or$col == $N or$col == $row) { print "N"; } else { print " "; } } print "\n"; } }  ## Task 3 This is the subtraction version of Euclid’s algorithm. sub task3 { my$a = @_[0];
my $b = @_[1]; while ($a != $b) { if ($a > $b) {$a -= $b; } else {$b -= $a; } } print "$a\n";
}

• Perl 6 will never have a single official implementation, instead anything that passes the spec tests can be considered Perl 6. The first official release of the spec tests happened in December of 2015. Perl did not always have the my keyword, so your belief that this works on all versions is utterly false. I suppose I can forgive you for a bit of ignorance considering you wrote my $a=@_[0] instead of the more correct my$a=$_[0] or even better my ($a,$b)=@_; and that you used the error prone C-style for loop instead of for my$col (1..$N){…} – Brad Gilbert b2gills Feb 4 '16 at 22:51 # 1991 - Fortran 90 From Wikipedia: The much delayed successor to FORTRAN 77, informally known as Fortran 90 (and prior to that, Fortran 8X), was finally released as ISO/IEC standard 1539:1991 in 1991 and an ANSI Standard in 1992. In addition to changing the official spelling from FORTRAN to Fortran, this major revision added many new features to reflect the significant changes in programming practice that had evolved since the 1978 standard ### “Hello, World” In particular, Fortran 90 adds free-form source input (yay!), which is nice even for Hello World. program say_my_name print '(A)', "Fortran 90 was made in (you guessed it) 1991" end program say_my_name  ### ASCII art “N” In the ASCII art task, the handy I0 format specifier from Fortran 95 has to go. Too bad if you want to print N for N ≥ 10¹⁰ program paint_N integer :: N, i character(len=500) :: fmt read*, N do i=1,N write(fmt, "('(', 2(A, ',', 'T', I11, ','), A, ')')") & "'N'", i, "'N'", N, "'N'" print fmt end do end program paint_N  ### Greatest common divisor To compute the GCD, we use Euclid's algorithm because Fortran 90 lacks the bitwise operations. (Even if ifort -e90 accepts them; gfortran has -std=f95 but no corresponding std=f90.) program Euclidean_GCD_algorithm integer :: a, b do read(*,*, END=1) a, b print*, gcd(a,b) end do 1 continue contains integer function gcd(a, b) integer, intent(in) :: a, b integer :: v, t gcd = a v = b do while (v /= 0) t = v v = mod(gcd, v) gcd = t end do end function gcd end program Euclidean_GCD_algorithm  • Oh my - we're officially into languages that are older than me. – Commander Coriander Salamander Apr 16 '15 at 5:56 • Well, I won't be doing any Fortran versions that are older than me. No thanks :-) – xebtl Apr 16 '15 at 7:34 # 1973 - COMAL Quite a number of COMAL resources can be found on the web. Since I have no prior exposure to COMAL (we are now well past my birth year), I'll quote and link some of them here. COMAL (Common Algorithmic Language) is a computer programming language developed in Denmark by Benedict Løfstedt and Børge R. Christensen in 1973. COMAL was created as a mixture of the prevalent educational programming languages of the time, BASIC, Pascal … The language was meant to introduce structured programming elements in an environment where BASIC would normally be used. I used OpenComal, originally by Jos Visser and forked to run on recent Linux systems by Christian Pietsch, to write and test these programs. Jos defines COMAL as A crossover between Basic and Pascal, with the best features of both and none of the drawbacks of either. OpenComal comes with nice documentation, which is more than detailed enough to make it easy to write the code. It also gives some history: In the early history of micro computing, resources … were scarce … BASIC was the language of choice back then. Almost all micro computers featured their own dialect of BASIC … Most of the time they lacked about everything necessary to develop well-structured and maintainable programs … The principles of structured programming were available of course, but structured languages like PASCAL were not really available for small micro's due to limitations in the micro's resource capacity and the then available compiler technology. Somewhere in Denmark a teacher named Borge Christensen understood the potential dangers of the BASIC habits and he [modified] an available BASIC interpreter so as to create a new language which should support structured programming concepts like PROCedures, FUNCtions and GOTO-less loops. The first Comal … interpreter was born. ### Task 1  10 PRINT "COMAL was made in 1973!"  Every line has to be numbered, but note that the line numbers are used only for editing — there is no GOTO. The COMAL executable is an editor and interpreter rolled into one. You enter the code; list prints it back to you nicely formatted (as the Compute! article linked above would have it: “You type in a BASIC program; when you list it back, it looks as if it has been changed to Pascal”). The line numbers allow you replace, edit, or delete certain lines. When you are satisfied, you run the program. Actually, this way of programming was quite fun — just remember to save often because the interpreter crashes sometimes. ### Task 2 COMAL uses postfix sigils to distinguish variable types. Thus n# is an integer, n$ a string, and n a floating point variable. Booleans are of the 1/0 variety and indices (for substrings or arrays, though the latter can be changed with DIM) start at 1.

   10 INPUT "Enter a number ": n#
20
30 n$:=" N" 40 50 FOR i:=1 TO n# DO 60 FOR j:=1 TO n# DO 70 n:=1+(j=1 OR j=i OR j=n#) 80 PRINT n$(n:n),
90   ENDFOR j
100   PRINT
110 ENDFOR i
120
130 END


Recursion is supported (the file TODO does state ”Heavily recursive Comal programs mess up the interpreter a bit”, but I had no problems with gcd). FUNCtion and PROCedure names have the same sigils as variables. A function or procedure may be declared CLOSED meaning that all variables are local (in this case, it does not change anything of course).

   10 INPUT "Enter two numbers ": a#, b#
20 PRINT gcd#(a#, b#)
30
40 FUNC gcd#(a#, b#) CLOSED
50   IF b#=0 THEN RETURN a#
60   RETURN gcd#(b#, a# MOD b#)
70 ENDFUNC gcd#

• Did you intend to leave the PRINT a," ",b? Seems like it was for debugging purposes. – kirbyfan64sos Apr 28 '15 at 22:22
• @kirbyfan64sos absolutely correct, thanks. – xebtl Apr 29 '15 at 8:25
• Is using floating point deliberate in task 3? – CJ Dennis May 2 '15 at 15:54
• @CJDennis Not really, except that they are easier to type and it does not matter for smaller inputs. But you are right that there is a range of larger numbers where integers work but floats don't (e.g. 971*983*991*997*967*937 = 854491261035335569 and one of its factors), so I changed the code to use integers. – xebtl May 2 '15 at 18:49

# 1985 - QuickBASIC

QuickBASIC is essentially the same thing as its later version QBasic, albeit with a few features that QBasic doesn't have (such as a compiler). It was part of a second generation of BASIC versions that moved more toward structured programming--eliminating the requirement for line numbers, tending toward using loops rather than gotos (though not exclusively), and allowing procedural abstraction via "subprograms."

(Wikipedia gave vague and possibly conflicting information on what control structures were available in the first version of QuickBASIC, and Google wasn't particularly helpful either; so if you see something that you know shouldn't be in here, let me know and I'll change it.)

CLS
PRINT "QuickBASIC was made in 1985!"
END


In QBasic for DOS, at least, the CLS command is needed to clear the screen between successive invocations--otherwise, you'll just keep adding a new QuickBASIC was made in 1985! line each time you run the program.

CLS
INPUT "Enter size of N: ", size
FOR i = 1 TO size
FOR j = 1 TO size
IF j = 1 OR j = i OR j = size THEN PRINT "N"; ELSE PRINT " ";
NEXT j
PRINT
NEXT i
END


The variables here don't have any type indicators and so are numeric by default. If you try to give the INPUT statement something non-numeric, it will print an error message and ask you again. Semicolon isn't a statement separator, it suppresses newline at the end of the PRINT statement.

CLS
INPUT "Enter two integers: ", a, b
WHILE a > 0
LET tmp = b
LET b = a
LET a = tmp MOD a
WEND
PRINT "GCD is"; b
END


The INPUT statement with multiple variables accepts two comma-separated numbers. The name of the WEND keyword probably derives from While-END, but the association with wend gives it a nice poetic touch.

# 2007 - GolfScript

GolfScript was one of the first languages created specifically for code golf.

;"GolfScript was made in 2007!"


The ; drops any user input from the stack before pushing the output string. I'm not familiar enough with GolfScript practices to know if this is necessary or not.

~:s{s{\.@.@=\.s=@+\.1=@+"N"" "if@@1-}s*;n\1-}s*;


Stores the size in s, then executes a nested loop via the {...}s* idiom. Most of the code in the inner loop is stack manipulation to generate the j==i || j==s || j==1 logic. Note the use of 1- instead of (, which was added to the language two weeks after the first version came out.

This could most likely be golfed further.

~{.@\%.}do;


Just a rip-off of the solution from the GolfScript website.

# 2000 - ActionScript

ActionScript is a member of the ECMAScript family, developed for scripting the animation software Flash. By making Flash programmable, it allowed for interactive menus, games, etc.

Version 1.0 was released in September of 2000 as part of Flash 5. Although Flash 4 had a simple scripting language known as "Actions," ActionScript 1.0 added significant new features such as user-defined functions, so I claim 2000 as the year of origin for ActionScript. (Source: Wikipedia)

On a personal note: ActionScript was the second programming language I learned, after QBasic. I still remember with great fondness the fractal generators, cipher machines, and vegetable-shooting games I created with it. Going back to it for this post was fun.

Note: These examples are tested with ActionScript 2.0, which is the oldest version I have access to. I've never used ActionScript 1.0. But as far as I know, I haven't used any 2.0-specific language features here.

The easy way would be to output the text to a debugging window via trace(). But this is an animation software--we can do better.

createTextField("field_txt", 0, 0, 0, 200, 50);
field_txt.text = "ActionScript was made in 2000!";


The next two examples assume that text boxes with the appropriate names and properties have already been created. One can do this programmatically, as above, or by putting them on the stage with the GUI. The latter saves a lot of typing, of course.

input_txt.onChanged = function() {
number = int(input_txt.text);
output_txt.text = "";
for(i = 0; i < number; i++) {
for(j = 0; j < number; j++) {
if(j == i || j == 0 || j == number - 1) {
output_txt.text += "N";
} else {
output_txt.text += " ";
}
}
output_txt.text += "\n";
}
}


It's helpful to set output_txt to a monospace font.

a_txt.onChanged = b_txt.onChanged = function() {
if(a_txt.text && b_txt.text) {
a = int(a_txt.text);
b = int(b_txt.text);
while(a > 0) {
tmp = b;
b = a;
a = tmp % a;
}
output_txt.text = "GCD is " + b;
} else {
output_txt.text = "";
}
}


Both examples 2 and 3 update the result live as you type in the input boxes.

# 2001 - Felix

Felix is a powerful, multi-paradigm programming language inspired by a mix of C++ and the ML langauges (heck, the creator was a member of the C++ commitee at one point). It's very powerful and pretty awesome, taking a very different approach to several concepts. It features a dynamic plugin system (YES!!!!), a C++ code generator (the standard library's string type is just a wrapper over the C++ std::string), and a nice syntax. It also takes a unique approach to things such as calls (like Nim, a.b == 'b a'), indexing (calling an integer with a sequence indexes it), a grammar defined in user-space (a.k.a. you can extend the grammar inside your Felix script), and lvalues/rvales (there are none!).

The only real issue is that lack of half-decent documentation, but there are plenty of examples (the driver, the web server, the utilities: all written in Felix) and a very helpful mailing list.

Also, when you read some of the mailing list posts describing how certain internals work, you seriously feel like you gained brain cells. ;)

println "Felix was made in 2001!";


proc ascii(n: int) = {
for var i in 0 upto n - 1 do
for var j in 0 upto n - 1 do
print (if j == 0 or j == i or j == (n - 1) then "N" else " ");
done
println "";
done
}

ascii $stdin.readln.int; // or stdin.readln.int.ascii;  ## Task 3 fun gcd(a: int, b: int) => if b == 0 then a else jump gcd(b, a % b); // ^ jump is for tail recursion match split_first(stdin.readln, " ") with | Some (a, b) => println$ gcd(a.int, b.int);
| #None       => ;
endmatch;


# 1986 - Oberon

Oberon is a language designed by Niklaus Wirth to increase the power of Modula-2 and decrease its complexity (to quote Wikipedia).

To me, it's just a slightly nicer version of Pascal, despite the ALL-CAPS KEYWORDS THAT MAKES IT LOOK LIKE YOUR PROGRAMS ARE SCREAMING IN PAIN. :)

MODULE print;

IMPORT Out;

BEGIN
Out.String("Oberon was made in 1987!"); Out.Ln;
END print.


    MODULE ascii;

IMPORT Out, In;

PROCEDURE Ascii(n: INTEGER);
VAR i, j : INTEGER;
BEGIN
i := 0; WHILE i < n DO
j := 0; WHILE j < n DO
IF (j = 0) OR (j = i) OR (j = n-1) THEN Out.String("N")
ELSE Out.String(" ") END; INC(j)
END; Out.Ln; INC(i)
END
END Ascii;

VAR n : INTEGER;
BEGIN
In.Int(n); Ascii(n)
END ascii.


MODULE gcd;

IMPORT Out, In;

PROCEDURE Gcd(a, b : INTEGER): INTEGER;
BEGIN
IF b = 0 THEN RETURN a
ELSE RETURN Gcd(b, a MOD b) END;
END Gcd;

VAR a, b : INTEGER;
BEGIN
In.Int(a); In.Int(b); Out.Int(Gcd(a, b), 0); Out.Ln
END gcd.


# 1978 - MATLAB

So Wikipedia was a bit ambiguous on the release date. But this was one of the options.

MATLAB is mathematical language based on numerical calculation. The newer versions do support symbolic calculation (via MuPAD) like Mathematica. The language is heavily matrix / vector based and most of the operators are defined for matrices with special cases for the element-wise use (* is matrix multiplication .* is element-wise multiplication).

With language as old as MATLAB, I can not make any guarantees on if the tasks would work for the first variants of the language.

'MATLAB was made in 1978'


Notice how I do not use ";" at the end. That woud suppress the output. The default behaviour is to save the result of any assignment-less result (like this) to variable "ans". Because there is no semicolon after the statement the contents of the assignment variable (ans here) are printed out. You could use fprintf(format, ...) also.

function [] = printn(n)
ROW = blanks(n);
for i=1:n
for j=1:n
if (j == 1) || (j == i) || (j == n)
ROW(j) = 'N';
else
ROW(j) = ' ';
end
end
fprintf('%s\n', ROW);
end
end


I have my doubts if strings were a part of the first version of the language but this is quite vanilla solution never the less. The empty brackets [] mean the function does not return any values.

function [value] = mygcd(a,b)
if (a == b) || (b == 0)
value = a;
else
A = max(a,b);
B = min(a,b);
while B  > 0
a = B;
B = mod(A,B);
A = a;
end
value = A;
end
end


Matlab does have gcd built-in so I used mygcd as the function name. I also assumed a and b are scalars. The stack-overflow also happened with the recursive version so I used iterative Euclid's algorithm. The function returns the value, so you'd need to print it yourself.

fprintf('gcd(%d, %d) = %d\n', 40, 15, mygcd(40, 15));

• You need to change your answer some bit, Your title is not as OP want, You used ** instead of # Also First task show mathematica instead of matlab. – kuldeep.kamboj Apr 20 '15 at 10:13
• @kuldeep.kamboj the first task does work in matlab also. The format is only a bit settings dependent. If you want to have settings independent format then you can use: fprintf('Matlab was made in 1978\n'); Like I wrote. – Puzzled Apr 20 '15 at 17:11
• I don't know what was the functionality of first version of Matlab, but Task 2 is a serious overkill. The sequence t=eye(n); t(:,1)=t(:,end)=1; t*='N'; t(t==0)=' '; disp(char(t)); does the job perfectly. The syntax of the first Matlab might be a bit different, but it must have had some "matrix" operations. Yet replacing loops for matrix operations is so obvious in Matlab, there are even functions created to easily replace a bunch of vector operations into a single matrix one (vide repmat). – pawel.boczarski Apr 20 '15 at 23:23
• Agreed on that fact. But given that the first version of matlab was that long ago, I'm quite sure the syntax was widely different back then (for example might not have had splicing ":" etc). For that reason I decided to use loops. (Otherwise I'd have to know the library reference for the first Matlab) – Puzzled Apr 22 '15 at 7:17

# 1982 - Maxima

Maxima is a free and open source computer algebra system based on a 1982 version of Macsyma. It is written in Common Lisp. As a programming language, it has a ALGOL-like syntax but a Lisp-like semantics.

print("Maxima was made in 1982!")$ ## Task 2 asciiartn (n) := printf (true, "~{~{~:[ ~;N~]~}~%~}", makelist (makelist (member (j, [1, i, n]), j, n), i, n))$


printf is a extremely powerful function. It provides the Common Lisp function format in Maxima.

### "Hello, World!" Variant

%put SAS was made in 1976!;


The %put statement is actually a macro statement. It writes all text up to the semicolon to the log.

### ASCII Art N

%let n = 7; /* Whatever N you want */

data _null_;
/* Read the macro variable N */
n = symgetn('n');

if n = 1 then put 'N';
else do;
line = cat('N', repeat(' ', n-3), 'N');
put line;

do i = 2 to n-1;
line = 'N';

if i = 2 then call cats(line, 'N');
else call catx(repeat(' ', i-3), line, 'N');

if i = n-1 then call cats(line, 'N');
else call catx(repeat(' ', n-i-2), line, 'N');

put line;
end;

line = cat('N', repeat(' ', n-3), 'N');
put line;
end;
run;


This uses the cat() family of functions and call routines for string concatenation. However, string concatenation can alternatively be performed using ||.

### GCD

%macro gcd(a, b);
%local a_ b_ c;

/* Store original inputs */
%let a_ = &a;
%let b_ = &b;

%do %until(%eval(&b = 0));
%let c = %sysfunc(mod(&a, &b));
%let a = &b;
%let b = &c;
%end;

%put The GCD of &a_ and &b_ is &a;
%mend gcd;


This defines a macro which call be called like %gcd(12, 15);. The result is written to the log.

# 1990 - zsh

The Z shell is a Unix shell in the family of sh, ksh, bash, etc. I'd never used it before today, but 1990 needed a language, and I knew a little Bash; this couldn't be too different, right?

echo zsh was made in 1990!


No quotes necessary.

for ((i = 0; i < $1; i++)); do for ((j = 0; j <$1 - 1; j++));
do
if (($i ==$j || $j == 0)); then echo -n 'N'; else echo -n ' '; fi done echo 'N'; done  Invoke as zsh task2.zsh 7. Note the C-inspired for loop syntax (though with semicolon and do/done); one quirk there is that the variable names don't use $ anywhere in the loop header. (Typically, shell variables stand without the $ only in assignments, like x=5.) The first command-line argument is available as $1. The double parens perform an arithmetic evaluation, which conveniently also supports comparison and boolean operators. Passing the -n option to echo suppresses the trailing newline; I decided to stop the inner loop short of the final column so I could use echo 'N' to print the last N and the newline at the same time.

gcd() {
if (($1)); then gcd$(($2 %$1)) $1; else echo$2;
fi
}

gcd $1$2


Invoke as zsh task2.zsh 2706 410.

Here we get to define a function gcd. It is called just like a shell command, with space-separated arguments. Within the function, parameters are referenced with the same $1, $2, etc. as command-line arguments to a script. By using arithmetic evaluation in the condition, we can test if the argument is nonzero the same way as in C or Python.

The oddest thing (to me) is that you don't return the return value--you output it to STDOUT. (The return command sets the function's exit status, which is problematic if you're dealing with values outside the 0 to 255 range!) If you need to store the result instead of displaying it, just use retval=$(gcd$1 $2). # 1992 - Dylan Dylan is a multi-paradigm programming language, that has support for both functional and object-oriented programming. It was originally written at Apple to be the programming language for the Newton, but that went wrong, and the Newton's software ended up written in a combination of C and a stripped-down version of Self named NewtonScript. Despite its syntax, Dylan is a Lisp derivative. Some of the syntax does show it, however: variable names like this-one and *this*one* are considered valid, and thus operators need to be seperated from their arguments by spaces. Dylan also has Lisp-style macros that can actually extend the syntax to some extent. For example, the for construct as used in the ASCII art example is actually a macro, not a built-in. Actually compiling a Dylan program is a bit of a hassle. You need to define at least a library, a module, and a library interchange file (LID), in three different files. Because both the library and the LID are basically only boilerplate for small programs like these, I have provided only the modules. OpenDylan, which I used, can generate all the necessary boilerplate for you using make-dylan-app <name>. ### Task 1 Module: task1 format-out("Dylan was created in 1992!\n");  ### Task 2 Module: asciin define function N (size :: <integer>) for (line from 1 to size) for (col from 1 to size) format-out( if (col = 1 | col = size | col = line) "N" else " " end if ); end for; format-out("\n"); end for; end function N; N(string-to-integer(application-arguments()[0]));  ### Task 3 Dylan has a built-in gcd function, so all you need to do is write an I/O wrapper: Module: gcd format-out("%d",apply(gcd,map(string-to-integer,application-arguments())));  However, if you want to write your own gcd, you can do it like this: Module: customgcd define function my-gcd (a :: <integer>, b :: <integer>) if (b = 0) a else my-gcd(b, modulo(a, b)) end if end function my-gcd; format-out("%d\n",apply(my-gcd,map(string-to-integer,application-arguments())));  This also shows how it is a multi-paradigm language: N from task 2 is written in imperative style, my-gcd is written in functional style. # 1977 - Icon Icon language designed by Ralph Griswold in 1977. It is very much inspired from Algol Languages family specially Pascal language. It have some specialized feature like goal directed execution, generators and string scanning. See Home Link # Task 1 procedure main() write("Icon was made in 1977"); end  # Task 2 procedure main(args) i := 0 n := args[1] repeat { j := 0 repeat { v := n-1 if j = 0 | j = v | i = j then writes("N") else writes(" ") j +:= 1; if j >= n then break } i +:= 1; write("") if i >= n then break } end  # Task 3 procedure main(args) a := args[1] b := args[2] while a ~= b do { if a > b then a -:= b else b -:= a } write(a) end  # 1998 - PIKT PIKT is a versatile system and network administration program. As such, it includes a scripting language. PIKT scripts are usually written to respond to certain events, but it is also possible to run PIKT scripts by themselves. The syntax for stand-alone scripts and alert scripts are slightly different. The following programs are stand-alone scripts to be run from the command line. Input is taken via command line arguments. The scripting language resembles a combination of awk and shell scripts, but is strongly typed. It has facilities for line-by-line (awk-style) processing of input data, and for inter-process communications. There's also a facility for accessing the previous run's variables. The tasks aren't very good to show this off, though. ### Task 1: begin output "PIKT was created in 1998!"  ### Task 2: begin set #n = #value($ARGV[1])
for #line=1 #line<=#n #line+=1
set $s = "" for #column=1 #column<=#n #column+=1 if #column==1 || #column==#n || #column==#line set$s .= "N"
else
set $s .= " " endif endfor output$s
endfor


The following modification to this script makes it print an N the size of the previous input. This ability might seem useless, but if you're running cron scripts it is not. %n refers to the value #n had the previous time the script was run.

begin
set #n = #value($ARGV[1]) for #line=1 #line<=%n #line+=1 set$s = ""
for #column=1 #column<=%n #column+=1
if #column==1 || #column==%n || #column==#line
set $s .= "N" else set$s .= " "
endif
endfor
output $s endfor  ### Task 3: begin set #a = #value($ARGV[1])
set #b = #value($ARGV[2]) while #b != 0 set #c = #a % #b set #a = #b set #b = #c endwhile output$text(#a)