## Programming Languages Through The Years

170

71

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> 2This should help. – swish – 2015-04-06T09:10:59.613 23 Wikipedia has a list for everything: this one for non-esoteric languages by year. – Sanchises – 2015-04-06T12:30:42.223 I purged a lot of comments which appeared to be obsolete or chatty. Please notify me of any comments that should be undeleted. For extended discussion, please move to [chat]. – Martin Ender – 2015-04-23T15:09:27.680 2Should 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 – 2015-05-03T02:51:32.970 2@CJDennis: as you noticed, people have been using common sense in how to code those tasks. In some of the languages here it would be very un-idiomatic or outright impossible to use loops (because they have no such concept). In other languages, recursion is similarly unfavourable. Just solve the tasks in a way that fits your language well; all that's required is that the result matches. As a matter of fact, I like this challange in part because it can really highlight some of the differences between languages, not just in syntax but in the way you approach problems. – ceased to turn counterclockwis – 2015-05-04T07:35:44.560 2Awesome question, and reading through all the diverse answers is very enlightening. Signed up to codegolf just to be able to post an answer :-) – Amos M. Carpenter – 2015-05-05T05:32:40.200 5I feel like making a second account just to get us past 1971. – marinus – 2015-05-05T10:49:19.240 2Being pedantic here, but I just noticed that one of the conditions for an answer being invalid is... "come[s] from a user that already answered in the last 5 years". Should probably be: "come[s] from a user who has already submitted an answer for one of the previous 5 years". Pretty sure that many a good answer would otherwise be invalid. ;-) – Amos M. Carpenter – 2015-05-11T07:07:55.343 6If 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 - 汤莱恩 – 2015-05-19T18:19:06.767 @BrianTompsett: I think we're done for. I've not been able to find a compiler or interpreter for any of the 1965 languages. – marinus – 2015-05-21T20:53:50.593 1@marinus - The rules do not require execution - well that is my reading. There is plenty of documentation on RPG II to enable a program to be written surely? – Brian Tompsett - 汤莱恩 – 2015-05-21T21:01:23.010 1 @marinus there is a working 1965 version of RPGII plus some other 1960s compielrs on that site FYI... – Brian Tompsett - 汤莱恩 – 2015-05-25T11:38:28.173 1For completeness' sake, could "The only exception is Y = 2015." be changed to "The only exception is Y ≥ 2015."? – Martin Ender – 2016-01-19T13:28:38.870 1 I take issue with Perl 5 and Perl 6 being considered the same language. Perl 4 => Perl 5 => Perl 6 is about the same amount of difference as C => C++ => Haskell. I can understand Perl 1-5 being considered the same language to a point, since they are all mostly backwards compatible (some esoteric features that you shouldn't use were removed). – Brad Gilbert b2gills – 2016-02-04T23:12:15.657 1It might be useful for future posters. (It at least helped me locate these older languages.) – None – 2020-03-10T08:46:10.200 What if someone makes a parser for Jacquard machine code? That's always possible... – A username – 2021-02-16T08:45:45.293 ## Answers 178 # 2013 - Dogescript Dogescript is a language created in 2013 by Zach Bruggeman. It is nothing more than a syntax-replacement for Javascript to make it read like the internal monologues of memetic Shiba Inus. ## Hello doge console dose loge with "Dogescript was made in 2013!"  ## ASCII Art such N much N much i as 0 next i smaller N next i more 1 very doge is ("N" + " ".repeat(N-2) + "N").split('') s[i] is "N"; console dose loge with doge.join('') wow wow  ## GCD such gcd_doge much doge, dooge rly dooge gcd_doge(dooge, doge % dooge) but rly doge smaller 0 -doge but doge wow wow  118Wow, such +1. Very answer. Much quality. – Alex A. – 2015-04-06T20:08:59.897 28I joined codegolf just to upvote this answer! – Derek Tomes – 2015-04-08T02:36:16.560 22I can't even read the GCD one with a straight face – Cole Johnson – 2015-04-09T07:18:55.710 16I can't not read gcd_doge as good_dog. Help – Yann – 2015-04-09T12:19:08.553 Fantastic. However, according to LANGUAGE.md, double quotes are not supported. Would love an explanation of the s[i] bit too! – Docteur – 2015-05-06T06:17:58.467 65 # 2015 - Retina Retina is a regex-based programming language, which I wrote to be able to compete in PPCG challenges with regex-only answers, without having the unnecessary overhead of calling the regex in some host language. Retina is Turing-complete. To prove it I've implemented a 2-tag system solver as well as Rule 110. It is written in C#, hence it supports both the .NET flavour (by default) and the ECMAScript flavour (via a flag). Retina can operate in multiple modes, but the most relevant one for computations (and the Turing-complete one) is Replace mode. In Replace mode you give Retina an even number of source files. These are then paired, the first of each pair being a regex, and the second a replacement. These are then executed in order, manipulating the input step by step. The regex can also be preceded by a configuration (delimited with ). The most important option (which makes Retina Turing-complete) is +, which makes Retina apply the replacement in a loop until the result stops changing. In the following examples, I'm also using ;, which suppresses output on intermediate stages. In each of the following submissions, each line goes in a separate source file. (Alternatively, you can use the new -s option and put all lines into a single file.) Empty files/lines are represented as <empty>. Files/lines containing a single space are represented as <space>. The explanations are quite long, so I've moved them to the end of the post. ## The Programs ### "Hello, World!" Variant <empty> Retina was made in 2015!  ### ASCII Art N This assumes that STDIN is terminated with a newline. ;^ # ;+(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)$1$1$1$1$1$1$1$1$1$1$2$3$4$5$6$7$8$9$10#
;#
<empty>
;\d
N
;.(?<=(?=(.*\n)).*)|\n
$1 ;N(?=N\n.*\n.*\n$)
<space>
;+N(?=.?(.)+\n.* (?<-1>.)+(?(1)!)\n)
<space>
;(?<=^.*\n.*\nN)N
S
;+(?<=\n(?(1)!)(?<-1>.)+S.*\n(.)+N?)N
S
S
<space>


### GCD

This requires that STDIN is not terminated with a newline.

;\b(?=\d)
#
;+(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)
$1$1$1$1$1$1$1$1$1$1$2$3$4$5$6$7$8$9$10# ;# <empty> ;\d 1 ;^(.+)\1* \1+$
$1 ;$
#:0123456789
;+^(?=1)(1*)\1{9}(#(?=.*(0))|1#(?=.*(?<3>1))|11#(?=.*(?<3>2))|111#(?=.*(?<3>3))|1111#(?=.*(?<3>4))|11111#(?=.*(?<3>5))|111111#(?=.*(?<3>6))|1111111#(?=.*(?<3>7))|11111111#(?=.*(?<3>8))|111111111#(?=.*(?<3>9)))
$1#$3
#|:.*
<empty>


## Explanations

### "Hello, World!" Variant

This is fairly trivial. It takes no input (i.e. an empty string), matches nothing and replaces it with Retina was made in 2015!. One can also make it work for arbitrary input, by replacing the pattern with [\s\S]* for instance. That would slurp STDIN and replace all of it with the output.

### ASCII Art N

This has quite a lot of stages. The idea is to convert the input to unary, create an N x N block of Ns and then "carve out" two triangles. Let's go through the individual stages. Remember that ; merely suppresses intermediate outputs, but + causes the replacement to be applied in a loop.

;^
#


Simple: prepend a # to the input. This will be used as a marker in the conversion to unary.

;+(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)
$1$1$1$1$1$1$1$1$1$1$2$3$4$5$6$7$8$9$10#  This converts one digit to unary. It takes the digits already converted (\d*) and repeats them 10 times. And then it takes the next digit and appends the appropriate number of digits. The actual value of the digits is irrelevant at this stage. When the # reaches the end of the number, the regex no longer matches, and the conversion is done. As an example, the number 127 will be processed as #127 1#27 111111111122#7 1111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111227777777#  where the last line contains exactly 127 digit characters. ;# <empty> ;\d N  Two simple stages which get rid of that # and then convert all the digits to N. In the following I'll use input 7 as an example. So now we've got NNNNNNN  The next stage ;.(?<=(?=(.*\n)).*)|\n$1


replaces each N with the entire string (remember that it contains a trailing newline), and also removes the trailing newline itself. Hence, this turns the single row into a square grid:

NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN


Now the upper triangle. First, we start things off by turning the N in the lower right corner into a space:

;N(?=N\n.*\n.*\n$) <space>  The lookahead ensures that we're modifying the correct N. This gives NNNNNNN NNNNNNN NNNNNNN NNNNNNN NNNNN N NNNNNNN NNNNNNN  And now ;+N(?=.?(.)+\n.* (?<-1>.)+(?(1)!)\n) <space>  is a regex which matches an N which is above or at the top left corner of a space character, and replaces it with a space. Because the replacement is repeated, this is essentially a flood-fill, which turns the 3rd octant from the initial space into more spaces: N N NN N NNN N NNNN N NNNNN N NNNNNNN NNNNNNN  And finally, we repeat the same thing with the bottom triangle, but we use a different character, so the already existing spaces don't cause a wrong flood fill: ;(?<=^.*\n.*\nN)N S  sets the seed: N N NN N NSN N NNNN N NNNNN N NNNNNNN NNNNNNN  Then ;+(?<=\n(?(1)!)(?<-1>.)+S.*\n(.)+N?)N S  does the flood-fill. N N NN N NSN N NSSN N NSSSN N NSSSSNN NSSSSSN  And finally S <space>  Turns those S into spaces and we're done: N N NN N N N N N N N N N N N NN N N  ### GCD GCD in unary is actually very trivial with regex. Most of this consists of the decimal to unary and unary to decimal conversion. This could be done more compactly, but this isn't a code golf, so... ;\b(?=\d) # ;+(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)$1$1$1$1$1$1$1$1$1$1$2$3$4$5$6$7$8$9$10#
;#
<empty>
;\d
1


These stages are essentially the same as above, except that both input numbers are converted, and the result uses 1s instead of Ns (not that it matters). So if the input was 18 24, then this would produce

111111111111111111 111111111111111111111111


Now

;^(.+)\1* \1+1


is the entire GCD computation. We match a common divisor by capturing a number of 1s, and then using backreferences to ensure that both numbers can be written by repeating that string (and nothing else). Due to how backtracking works in the regex engine (i.e. that .+ is greedy), this will always yield the greatest common divisor automatically. Since the match covers the entire string, we simply write back the first capturing group to get our GCD.

Finally, the unary to decimal conversion...

;$#:0123456789  Append a marker #, a delimiter : and all digits to the string. This is necessary, because you can't produce new characters conditionally in a regex replacement. If you want conditional replacement, you need to pull the characters from the string itself, so we put them there. ;+^(?=1)(1*)\1{9}(#(?=.*(0))|1#(?=.*(?<3>1))|11#(?=.*(?<3>2))|111#(?=.*(?<3>3))|1111#(?=.*(?<3>4))|11111#(?=.*(?<3>5))|111111#(?=.*(?<3>6))|1111111#(?=.*(?<3>7))|11111111#(?=.*(?<3>8))|111111111#(?=.*(?<3>9)))$1#$3  This is the inverse of the unary expansion earlier. We find the largest multiple of 10 that fits into the current string. Then we choose the next digit based on the remainder, and divide the multiple by 10, while moving the marker through the digits. #|:.* <empty>  And lastly just a cleanup step to get rid of the marker, delimiter and the helper digits. I think you should add instruction to convert numeric input to unary string, and instruction to convert unary string back to numeric input. The conversion with pure regex is cool but far too clunky. – n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ – 2015-04-06T10:10:56.120 8+1 I was pretty sure 2015 submission would be a language for CodeGolf use. – Zero Fiber – 2015-04-06T10:31:42.037 @n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ I was considering that earlier. I think for most code golfs, I'd probably just take Unary input (unless the challenge explicitly specifies "decimal" or something...). I thought about doing the same for this, but this is not a code golf, and I wanted to show that I can handle decimal input and output as well. – Martin Ender – 2015-04-06T18:03:30.890 6Excellent work. Retina is really cool. And as an aside, it's also really cool seeing the diamond next to your name! :) – Alex A. – 2015-04-06T20:08:22.320 Funny that although old languages are favored in this competition, this most youngest one is still winning =) – Claudiu – 2015-04-29T03:55:42.027 @Claudiu "winning" except that LOLCODE has more than twice as many upvotes. ;) – Martin Ender – 2015-04-29T09:26:10.090 60 # 2013 - Snap! Snap! is a language based on Scratch, made at Berkeley University. It is an upgrade to Scratch featuring first-class data and custom blocks (functions). Like Scratch, it is not text based, but rather done by visual "blocks" that snap together. Snap!, written in JavaScript, is the successor to BYOB, which was written in Squeak Smalltalk. Snap! was beta released for public consumption in March 2013. Snap! is actually not an esoteric language. It is used as the programming language for the Beauty and Joy of Computing (BJC) AP CS course at Berkeley and others. I helped out with testing and stuff. ## "Hello World" variant ## ASCII Art "N" This uses the stdlib for some of the blocks. Pretty basic looping here. Takes an input. Then we just add it all together and say it (result for n=5): I took the liberty here to just use 2 spaces instead of 1, because Snap! doesn't say stuff in monospace. ## GCD The Euclidean algorithm isn't very fast, but it works, and is pretty simple. (Sorry, i made a typo in the block name. Now i closed the tab without saving. It'll just have to stay.) This function definition will then produce this block: 3This looks a LOT like programming in Alice... – mbomb007 – 2015-04-06T16:42:30.323 4That's what you get with block based languages. Come to thing of it, lots of languages look alike. ;) – Scimonster – 2015-04-06T16:51:13.113 1Even Scratch has a mod function so I'd assume that you could make the GCM/GCD function faster with a block based on if (b==0) then a else GCM(b, a%b) – Alchymist – 2015-04-07T10:57:58.867 57 # 2007 - LOLCODE ### Language History LOLCODE was created in 2007 by Adam Lindsay, a researcher at Lancaster University. Its syntax is based on the lolcats memes popularized by Cheezburger, Inc. ### "Hello, World!" Variant HAI VISIBLE "LOLCODE wuz maed in 2007!" KTHXBYE  ### ASCII Art N HAI BTW, read n from stdin GIMMEH n BTW, convert n from YARN to NUMBR n R PRODUKT OF n AN 1 BOTH SAEM n AN 1, O RLY? YA RLY VISIBLE "N" NO WAI VISIBLE "N"! I HAS A butt ITZ 1 IM IN YR toilet UPPIN YR butt TIL BOTH SAEM butt AN DIFF OF n AN 1 VISIBLE " "! IM OUTTA YR toilet VISIBLE "N" I HAS A kat ITZ 2 IM IN YR closet UPPIN YR kat TIL BOTH SAEM kat AN n VISIBLE "N"! BOTH SAEM kat AN 2, O RLY? YA RLY VISIBLE "N"! NO WAI I HAS A doge ITZ 1 IM IN YR l00p UPPIN YR doge TIL BOTH SAEM doge AN DIFF OF kat AN 1 VISIBLE " "! IM OUTTA YR l00p VISIBLE "N"! OIC I HAS A brd ITZ 1 IM IN YR haus UPPIN YR brd TIL BOTH SAEM brd AN DIFF OF n AN kat VISIBLE " "! IM OUTTA YR haus VISIBLE "N" IM OUTTA YR closet VISIBLE "N"! I HAS A d00d ITZ 1 IM IN YR lap UPPIN YR d00d TIL BOTH SAEM d00d AN DIFF OF n AN 1 VISIBLE " "! IM OUTTA YR lap VISIBLE "N" OIC KTHXBYE  Values are read as strings (YARNs) from stdin using GIMMEH. They can be converted to numeric (NUMBRs) by multiplying by 1. Values are printed to stdout using VISIBLE. By default a newline is appended, but it can be suppressed by adding an exclamation point. ### GCD HAI GIMMEH a a R PRODUKT OF a AN 1 GIMMEH b b R PRODUKT OF b AN 1 I HAS A d00d ITZ 1 IM IN YR food UPPIN YR d00d TIL BOTH SAEM b AN 0 I HAS A kitty ITZ a I HAS A doge ITZ b a R doge b R MOD OF kitty AN doge IM OUTTA YR food VISIBLE SMOOSH "gcd is " a KTHXBYE  SMOOSH performs string concatenation. 14Finally, a language everyone can understand. – ASCIIThenANSI – 2015-04-12T20:05:31.807 28IM IN YR toilet UPPIN YR butt Nice variable names – Cole Johnson – 2015-04-13T02:51:03.817 13@ColeJohnson: I always try to choose variable names that make sense in the situation rather than x1, x2, etc. – Alex A. – 2015-04-13T04:11:17.377 2Hilarious. I should not read this at work. – Alan Hoover – 2015-05-11T15:22:09.743 @AlanHoover: Clearly teh lolz are more important than teh jobz. – Alex A. – 2015-05-11T15:23:38.167 44 # 1982 - PostScript PostScript is a language for creating vector graphics and printing. Adobe was founded in 1982, and their first product was PostScript. The language was used in printers: the commands are interpreted by the printer to create a raster image, which is then printed onto the page. It was a very common component of laser printers well into the 1990s. But it’s obviously quite CPU intensive on the printer, and as computer processors became more powerful, it made more sense to do the rasterisation on the computer than the printer. PostScript has largely gone away on consumer printers, although it still exists on a lot of more high-end printers. The standard which replaced PostScript is a little-known format called PDF. PostScript had fallen out of fashion by the time I started programming, but I learnt a little bit while I was in university as another way of creating documents for TeX. It was quite different to other programming languages I’d used (reverse infix notation, stack, printing to a page instead of a console), but it was nice to dust off this old language for some fun. Since PostScript is a printing language, it seems more appropriate to use it to print something then send an output to the console. ## Task 1 /Courier findfont 12 scalefont setfont newpath 100 370 moveto (PostScript was made in 1982!\n) show  The first few lines set up a canvas to draw on. Then the moveto command tells PS to draw at a particular position, and show prints the string to the page. Note that parentheses mark a string in PostScript, not quotation marks. ## Task 2 /asciiartN {% stack: N row col % output: draws an "ASCII art" N % PostScript doesn't allow you to pass variables directly into a function; % instead, you have to pass variables via the global stack. Pop the variables % off the stack and define them locally. 6 dict begin /row exch def /col exch def /N exch def % Define how much space will be between each individual "N" /spacing 15 def % Get the width of the "N". We need this to know where to draw the right-hand % vertical /endcol col spacing N 1 sub mul add def % One row is drawn at a time, with the bottom row drawn first, and working % upwards. This stack variable tracks which column the diagonal is in, and so % we start on the right and work leftward /diagcol endcol def % Repeat N times: draw one row at a time N { % Left-hand vertical of the "N" col row moveto (N) show % Right-hand vertical of the "N" endcol row moveto (N) show % Diagonal bar of the "N" diagcol row moveto (N) show % Advance to the next row. This means moving the row one space up, and the % diagonal position one place to the left. /row row spacing add def /diagcol diagcol spacing sub def } repeat end } def 1 100 200 asciiartN 3 150 200 asciiartN 5 230 200 asciiartN  I wrote a function for drawing the “ASCII art” N, but there’s no way for PostScript functions to take an argument. Instead, you push your arguments to the stack, then get them back off. That’s the /x exch def line. An example: suppose the stack is 8 9 2. First we push the name /x to the stack, so the stack is 8 9 2 /x. The exch operator swaps the two stack values, so now the stack is 8 9 /x 2. Then def pops the top two stack values, and defines /x to have the value 2. The stack is now 8 9. When I started using PostScript, I found this a little confusing. I’d read about the stack as a theoretical concept, but this was the first time I was using it in practice. The rest of the function is some drawing code: start at the bottom right-hand corner, filling in a row at a time from left-to-right-to-diagonal. ## Task 3 /modulo {% stack: x y % output: returns (x mod y) 3 dict begin /y exch def /x exch def % If x = y then (x mod y) == 0 x y eq {0} { % If x < y then (x mod y) == x x y lt {x} { % If x > y then subtract floor(x/y) * y from x /ycount x y div truncate def /x x ycount y mul sub def /x x cvi def x } ifelse } ifelse } def /gcd {% stack: a b % returns the gcd of a and b 2 dict begin /b exch def /a exch def % I'm using the recursive version of the Euclidean algorithm % If b = 0 then return a b 0 eq {a} { % Otherwise return gcd(b, a mod b) /a a b modulo def b a gcd } ifelse } def /displaygcd {% stack: a b xcoord ycoord % displays gcd(a,b) at position (xcoord, ycoord) 5 dict begin /ycoord exch def /xcoord exch def /b exch def /a exch def /result a b gcd def xcoord ycoord moveto result 20 string cvs show % end } def 8 12 100 80 displaygcd 12 8 150 80 displaygcd 3 30 200 80 displaygcd 5689 2 250 80 displaygcd 234 876 300 80 displaygcd  Again, I used a form of Euclid’s algorithm, but I’d forgotten that PostScript has a built in modulo operator, so I had to write my own. This turned out to be a useful reminder of the constraints of stack-based programming. My first implementation of modulo was based on recursion: modulo(x, y) if (x = y) return 0 elif (x < y) return x else return module(x - y, y)  which is fine until you try to run this when x is large and y is small (e.g. 5689 and 2). You can only have up to 250 elements on the stack, and so I was blowing well past the stack limit. Oops. I had to go back to the drawing board on that one. The GCD code itself is fairly simple. But just as functions can’t take arguments, so they don’t have return values. Instead, you have to push the result to the stack where somebody else can pop it off later. That’s what the a and b a gcd lines do: when they’ve finished evaluating, they push the value to the stack. If you put all the code in a document and print it, this is what the output looks like: 9Haha I love the photograph of the printed piece of paper. Feels appropriate for 1982. – Alex A. – 2015-04-17T14:21:27.603 1Also, thanks for your description of how you got a (literal) stack overflow--now I understand more intuitively why languages have a max recursion depth. – DLosc – 2015-04-17T21:11:37.443 2@AlexA.: Yeah, but a dot-matrix printout (with holes on the sides of the paper) would've been even more appropriate. ;-) – Amos M. Carpenter – 2015-05-05T06:41:34.757 @AmosM.Carpenter: not really, I don't think any dot-matrix printer ever supported PostScript. It's always been pretty tied to laser printers. – ninjalj – 2017-12-29T11:40:24.603 42 # 2009 - ><> Inspired by Befunge, ><> (Fish) is an esoteric stack-based 2D language, i.e. program flow can be up, down, left or right. The initial version of ><> featured multithreading where [ and ] created and ended threads, but for simplicity reasons these instructions were changed to creating and removing new stacks respectively. The current official interpreter for ><> can be found here. Unfortunately, the link to the old interpreter on Esolang wiki is broken. ## "Hello, World!" Variant "!9002 ni edam saw ><>"l?!;obb+0.  Note how the string is written backwards — ><> doesn't technically have strings, with the only data type being a weird mix of char, int and float. " toggles string parsing, pushing each character onto the stack until a closing " is met. The second half of the code then pushes the length of the stack l, checks if it's zero ?! and if so the program terminates ;. Otherwise the instruction pointer continues, outputting the top of the stack with o before executing bb+0., which teleports the pointer to position (22, 0) just before the l, creating a loop. ## ASCII Art N &0 > :&:&:*=?; :&:&% :0=?v :&:&1-=?v :{:{-&:&,{=?v " " o \ > ~"N"o v + > ~"N"oao v 1 >"N"o v \ < /  With spacing for clarity. You can try this out at the new online interpreter here and see the instruction pointer go around and around — just remember to enter a number in the "Initial Stack" textbox. If you're running via the Python interpreter, use the -v flag to initialise the stack, e.g. py -3 fish.py ascii.fish -v 5  For this program, we put the input n into the register with & and push a 0, which we'll call i for "iterations". The rest of the program is a giant loop which goes like this: :&:&:*=?; If i == n*n, halt. Otherwise ... :&:&% Push i%n :0=?v If i%n == 0 ... >~"N"o Print "N" :&:&1-=?v Else if i%n == n-1 ... >~"N"oao Print "N" and a newline :{:{-&:&,{=?v Else if i%n == i//n, where // is integer division... >~"N"o Print "N" " "o Otherwise, print a space 1+ Increment i  Then we repeat the loop from the beginning. The arrows ^>v< change the direction of program flow and the mirrors /\ reflect the direction of program flow. ## GCD >:{:}%\ ;n{v?:/ v~@/  Here's an example of what a golfed ><> program might look like. Once again, you can try this in the online interpreter (enter two comma-separated values in the "Initial stack" box, e.g. 111, 87) or by using the -v flag of the Python interpreter, e.g. py -3 fish.py gcd.fish -v 111 87  This program uses the Euclidean algorithm. Here's a GIF I prepared earlier: Note that ><> is toroidal, so when the bottom left v instruction is executed the instruction pointer goes downwards, wraps around, and reappears at the top. Edit: By making the code run entirely from right to left, @randomra managed to shave three bytes with <~@v!?:%}:{: ;n{/  Guess I didn't golf it down enough :) 28And that was how I found out that the name ><> is a palindrome. – Zev Eisenberg – 2015-04-09T11:54:04.620 33 # 2012 - Element This is a language that I invented in early 2012 to be a simple golfing language. By this, I mean that there is very little to no operator overloading. The operators are also simpler and fewer in number than most modern golfing languages. The most interesting features of this language are its data structures. There are two stacks and a hash that are used to store information. The m-stack is the main stack, where arithmetic and most other operations take place. When data is inputted or printed, this is where it goes or is retrieved from. The c-stack is the control stack. This is where boolean arithmetic takes place. The top values of the c-stack are used by If and While loops as the condition. The hash is where variables are stored. The ; and ~ store and retrieve data from the hash, respectively. Element is a very weakly typed language. It uses Perl's ability to freely interpret numbers as strings and vice-versa. While I'm at it, I might as well include all the documentation for the language. You can find the original 2012 interpreter, written in Perl, right here. Update: I have created a more usable version, which you can find right here. OP the operator. Each operator is a single character STACK tells what stacks are affected and how many are popped or pushed "o" stands for "other effect" HASH tells if it involves the hash x & y represent two values that are already on the stack, so the effect of the operator can be more easily described OP STACK HASH DESCRIPTION text ->m --whenever a bare word appears, it pushes that string onto the main stack _ o->m --inputs a word and pushes onto main stack  m->o --output. pops from main stack and prints xy; mm-> yes --variable assignment. the top stack element y is assigned the value x ~ m->m yes --variable retrieval. pops from main stack, pushes contents of the element with that name x? m->c --test. pops x and pushes 0 onto control stack if x is '0' or an empty string, else pushes 1 ><= m->c --comparison. pops two numbers off of stack and performs test, pushes 1 onto control stack if true and 0 if false ' m->c --pops from main stack and pushes onto control stack " c->m --pops from control stack and pushes onto main stack &| cc->c --AND/OR. pops two items from control stack, performs and/or respectively, and pushes result back onto control stack ! c->c --NOT. pops a number off of control stack, pushes 1 if 0 or empty string, 0 otherwise [] c --FOR statement (view the top number number from control stack and eval those many times) {} c --WHILE (loop until top number on control stack is 0, also does not pop) # m-> --discard. pops from main stack and destroys ( m->mm --pops from main stack, removes first character, pushes the remaining string onto stack, and pushes the removed character onto stack ) m->mm --pops from main stack, removes last character, pushes the remaining string onto stack, and pushes the removed character onto stack +-*/%^ mm->m --arithmetic. pops two most recent items, adds/negates /multiplies/divides/modulates/exponentiates them, and places the result on the stack xy@ mm->o --move. pops x and y and moves xth thing in stack to move to place y in stack x$      m->m         --length. pops x and pushs length of x onto the stack
xy:    mm->o         --duplication. pops x and y and pushes x onto the stack y times
xy.    mm->m         --concatination. pops x and y and pushes x concatonated with y
\        o           --escapes out of next character, so it isn't an operator and can
be pushed onto the stack
,      m->mm         --character conversion. pops from main stack, coverts it to char
and pushes, and converts to num and pushes
Newlines and spaces separate different elements to be pushed
onto the stack individually, but can pushed onto the stack using \


## Task 1 - Print Text

Element\ was\ made\ in\ 2012\!


One of the more awkward parts of the language is the lack of string delimiters, which is why escape characters are needed in this string. The  at the end prints the string.

## Task 2 - ASCII Art N

_+'[y~1+y;0[1+4:"2:'=1=|y~=|\ [#N]"#]\
]


Here, you will witness some stack manipulation. To make the explanation a little easier to format, I'll replace the newline with an L and the space with an S.

_+'[y~1+y;0[1+4:"2:'=1=|y~=|\S[#N]"#]\L]
_+'      input line, convert to #, move to c-stack
[        FOR loop
y~1+y;  increment the y-pos
0       set the x-pos (the top # on the stack) to zero
[       FOR loop
1+4:   increment x-pos and make 3 additional copies (4 is total #)
"2:'   make a copy of the N size on the main stack
=      if x-pos == size
1=     or if x-pos == 1
y~=|   of if x-pos == y-pos
\S     (always) push a space
[      the IF body (technically a FOR loop)
#N    if true, remove the space and push an N
]      end IF
      output the pushed character
"#     remove the result of the conditional
]       end x-pos FOR
\L     output a newline
]        end y-pos FOR


After doing some extreme golfing of this answer, I found a 39 byte solution, although it is much more complicated.

_'1[y~+y;[#1+3:"2:'%2<y~=|\ [#N]"]\
]


## Task 3 - GCD

__'{"3:~2@%'}


This is a stack-based method.

__                 input the two numbers
'                use one of the number as a condition so the WHILE loop starts
{        }      a WHILE loop. Repeats while the c-stack has a true value on top
"              get the number back from the c-stack to do operations on it
3:            make it so that there are threes copies on the stack
~           takes one of the copies from earlier and converts it to a zero
2@         take the top item on the stack and move it behind the other two #s
%        modulo operation
'       use this number as the condition
since one number is zero (and on the c-stack) print the
other number, which is on m-stack


29

# 2012 - Julia

### Language History

Julia was developed in 2012 by Jeff Bezanson, Stefan Karpinski, and Viral Shah while Jeff was a student at the Massachussets Institute of Technology (MIT), advised by professor Alan Edelman. They were motivated by a desire for a programming language that was open source, fast, and dynamic (among many other things) while maintaining ease of use in a variety of applications. The product was Julia, a fresh approach to high performance scientific computing.

### "Hello, World!" Variant

println("Julia was made in 2012!")


Printing to STDOUT in Julia is quite simple!

### ASCII Art N

function asciin(n)
# Create an nxn matrix of spaces
m = fill(" ", (n, n))

# Fill the first and last columns with "N"
m[:,1] = m[:,n] = "N"

# Fill the diagonal elements with "N"
setindex!(m, "N", diagind(m))

# Print each row of the matrix as a joined string
for i = 1:n
println(join(m[i,:]))
end
end


The code is indented for readability, but Julia imposes no restrictions on whitespace.

### GCD

function g(a, b)
b == 0 ? a : g(b, a % b)
end


The last thing listed in the function is implicitly returned.

28

# 1988 - Mathematica

Or should I call it Wolfram Language?

## Task 0

The creator of Mathematica is Stephen Wolfram, the Founder and CEO of Wolfram Research. Before the development of Mathematica, he was a physicist. There was a huge amount of algebraic calculation in physics, so he became a user of Macsyma.

Wolfram got his PHD in 1979, when he was 20. He thought that he needed a better CAS than Macsyma to do physics, so he began to write SMP (the "Symbolic Manipulation Program"). The first version of SMP was released in 1981. SMP was the predecessor of Mathematica. Though it had a deep influence on Mathematica, none of its code was ever used for Mathematica.

In 1986, Wolfram decided to write an "ultimate computation system". He started writing the code in 1986, and founded the Wolfram Research in 1987. Finally, Mathematica 1.0 was released on June 23, 1988.

I didn't find Mathematica 1.0. In fact, Mathematica 1.0 had neither a Windows nor a Linux version. But I found Mathematica 2.0 on a Chinese website. It can still be run on Windows XP.

## Task 1

Print["Mathematica was made in 1988!"]


Or simply:

"Mathematica was made in 1988!"


## Task 2

In today's Mathematica, we can write:

asciiArtN[n_] := Print @@@ SparseArray[{i_, 1 | i_ | n} -> "N", {n, n}, " "]


Just like Julia and R, this is a matrix solution. In Mathematica, you can define a sparse matrix using pattern matching.

However, SparseArray was introduced in Mathematica 5.0, so we can't use it in Mathematica 1.0.

Here is a solution that works in Mathematica 1.0:

asciiArtN[n_] := Block[{f},
f[i_, 1]  = "N";
f[i_, i_] = "N";
f[i_, n]  = "N";
f[__]     = " ";
Apply[Print, Array[f, {n, n}], 1];
]


We can't write f[i_, 1 | i_ | n] = "N" because Alternatives was introduced in Mathematica 2.0.

## Task 3

We can just use the built-in function:

gcd = GCD


Or we can use the definition of the GCD:

gcd = Max[Intersection @@ Divisors[{##}]] &;


Or we can use the LCM, though more commonly LCM is computed from GCD:

gcd = Times[##]/LCM[##] &;


Or we can use the Euclidean algorithm with pattern matching:

gcd[a_, 0] := a
gcd[a_, b_] := gcd[b, Mod[a, b]]


Or as an anonymous function:

gcd = If[#2 == 0, #1, #0[#2, Mod[##]]] &;


All the functions above were introduced in Mathematica 1.0.

3This is a much better answer than mine. I'll delete mine. – Martin Ender – 2015-04-16T13:55:22.190

24

# 2014 - CJam

CJam was created by PPCG user aditsu and was released around April 2014.

## "Hello, World!" Variant

"CJam was made in 2014!"


CJam automatically prints the contents of the stack at the end of the program

## ASCII Art N

ri:R'#*a_R2-,{_)S*'#+\R((-zS*+}%+\+R<zN*


Code explanation:

ri:R                                       "Read the input as integer in R";
'#*a                                   "Get a string of R # and wrap it in an array";
_R2-,{                }%           "Copy that string and then run this loop R-2";
"times for the diagonal";
_)S*                         "Get iteration index + 1 spaces";
'#+                      "Append the hash";
\R((-zS*+             "Append remaining spaces";
+\+        "Append and prepend the initial # string";
R<      "Take only R columns/rows. This is for";
"tackling input 1";
zN*   "Transpose and join with new lines";


Takes the height/width of N as input via STDIN. Try it online here

## GCD

l~{_@\%}h;


Takes the two numbers as input via STDIN. Try it online here

I realize this isn't [code-golf], but you can shorten the ASCII-art N program to ri_S*0'NtW'Nta1$*\,Sf*'Nf+..e>N* in modern CJam. – Esolanging Fruit – 2018-06-10T07:16:10.330 24 # 1999 - XSLT The World Wide Web Consortium (W3C) created XSLT for transforming XML into HTML, text, etc. The following examples assume input is enclosed in <input>..</input> tags. ## Task 1 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" indent="no"/> <xsl:template match="/input">XSLT was made in 1999!</xsl:template> </xsl:stylesheet>  This one is simple. It matches an input tag at the top level and replaces it with the desired output. ## Task 2 <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" indent="no"/> <xsl:template match="/input"> <xsl:call-template name="loop"> <xsl:with-param name="i">1</xsl:with-param> <xsl:with-param name="n"> <xsl:value-of select="."/> </xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template name="loop"> <xsl:param name="i"/> <xsl:param name="n"/> <xsl:choose> <xsl:when test="$i = 1 or $i =$n">
<xsl:text>N</xsl:text>
<xsl:call-template name="spaces">
<xsl:with-param name="n">
<xsl:value-of select="$n - 2"/> </xsl:with-param> </xsl:call-template> <xsl:text>N&#13;&#10;</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>N</xsl:text> <xsl:call-template name="spaces"> <xsl:with-param name="n"> <xsl:value-of select="$i - 2"/>
</xsl:with-param>
</xsl:call-template>
<xsl:text>N</xsl:text>
<xsl:call-template name="spaces">
<xsl:with-param name="n">
<xsl:value-of select="$n -$i - 1"/>
</xsl:with-param>
</xsl:call-template>
<xsl:text>N&#13;&#10;</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="$i &lt;$n">
<xsl:call-template name="loop">
<xsl:with-param name="i">
<xsl:value-of select="$i + 1"/> </xsl:with-param> <xsl:with-param name="n"> <xsl:value-of select="$n"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="spaces">
<xsl:param name="n"/>
<xsl:if test="$n &gt; 0"> <xsl:text> </xsl:text> <xsl:call-template name="spaces"> <xsl:with-param name="n"> <xsl:value-of select="$n - 1"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>


This one defines 2 recursive templates, loop and spaces. loop with parameters i and n will generate the desired output for n, starting at position i. spaces with parameter n will generate n spaces.

## Task 3

Input for this must be in <input><num>..</num><num>..</num></input> tags.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no"/>
<xsl:template match="/input">
<xsl:call-template name="gcd">
<xsl:with-param name="a"><xsl:value-of select="num[1]"/></xsl:with-param>
<xsl:with-param name="b"><xsl:value-of select="num[2]"/></xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="gcd">
<xsl:param name="a"/>
<xsl:param name="b"/>
<xsl:choose>
<xsl:when test="$b = 0"><xsl:value-of select="$a"/></xsl:when>
<xsl:otherwise>
<xsl:call-template name="gcd">
<xsl:with-param name="a"><xsl:value-of select="$b"/></xsl:with-param> <xsl:with-param name="b"><xsl:value-of select="$a mod $b"/></xsl:with-param> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>  This one is just a recursive template gcd that uses the Euclidean algorithm. And they say INTERCAL is weird! – kirbyfan64sos – 2015-08-18T19:44:05.103 2@kirbyfan64sos To be fair, it shouldn't be used for this stuff anyways... – LegionMammal978 – 2015-08-20T01:12:35.633 24 # 1990 - Haskell Haskell is a popular (or should I say: the most popular?) pure functional language. It sticks out from the mainstream by its unusual evaluation model (by default, everything is lazy or, technically, non-strict) and by its Hindley-Milner based type system which, even now, is still amongst the most powerful out there. ## Task 1 main = putStrLn "Haskell was made in 1990!"  ## Task 2 -- Infinite list of growing letters 'N' bigNs :: [[[Char]]] bigNs = ["N"] : ["NN","NN"] : [ ins (ins 'N' t)$ map (ins ' ') n | n@(t:_) <- tail bigNs ]

-- Insert a new element after the head (i.e. at the second position).
ins :: a -> [a] -> [a]
ins x (l:ls) = l:x:ls


Demo, print the whole infinite list (until user aborts, or the world ends...)

GHCi> mapM_ (putStrLn . unlines) bigNs
N

NN
NN

N N
NNN
N N

N  N
NN N
N NN
N  N

N   N
NN  N
N N N
N  NN
N   N

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

...


Of course, you can easily get to a single one of these, by accessing only one element of the infinite list:

main :: IO ()
main = do
i <- readLn
putStrLn . unlines $bigNs!!i  ## Task 3 gcd' :: Integer -> Integer -> Integer gcd' a 0 = a gcd' a b = gcd' b$ amodb


24

# 1972 - INTERCAL

And you thought Fortran and Cobol were weird. This is insane!

## Task 1

DO ,1 <- #27
DO ,1SUB#1 <- #110
DO ,1SUB#2 <- #32
DO ,1SUB#3 <- #72
PLEASE DO ,1SUB#4 <- #136
DO ,1SUB#5 <- #88
DO ,1SUB#6 <- #136
PLEASE DO ,1SUB#7 <- #64
DO ,1SUB#8 <- #80
DO ,1SUB#9 <- #46
PLEASE DO ,1SUB#10 <- #22
DO ,1SUB#11 <- #104
DO ,1SUB#12 <- #184
PLEASE DO ,1SUB#13 <- #202
DO ,1SUB#14 <- #78
DO ,1SUB#15 <- #48
PLEASE DO ,1SUB#16 <- #96
DO ,1SUB#17 <- #128
DO ,1SUB#18 <- #162
PLEASE DO ,1SUB#19 <- #110
DO ,1SUB#20 <- #32
DO ,1SUB#21 <- #114
PLEASE DO ,1SUB#22 <- #120
DO ,1SUB#23 <- #240
DO ,1SUB#24 <- #128
PLEASE DO ,1SUB#25 <- #208
DO ,1SUB#26 <- #200
DO ,1SUB#27 <- #52
DO READ OUT ,1
DO GIVE UP


I'm not going to try to explain INTERCAL's system of input and output; just read this and hope you don't die.

## Task 2

DO WRITE IN 7
DO .1 <- .7
DO .2 <- #1
PLEASE DO (1010) NEXT
DO .8 <- .3
DO .5 <- .7
DO .6 <- .8
DO ,9 <- #2

DO (100) NEXT
DO (1) NEXT

(100) DO (99) NEXT
DO ,9SUB#1 <- #142
DO ,9SUB#2 <- #114
PLEASE DO READ OUT ,9
DO ,9SUB#1 <- #176
DO ,9SUB#2 <- #80
PLEASE DO READ OUT ,9
PLEASE GIVE UP

(99) DO .1 <- .7
DO .2 <- #1
PLEASE DO (1010) NEXT
DO .1 <- '.3~.3'~#1
PLEASE DO FORGET .1
DO RESUME #1

(1) PLEASE DO (3) NEXT
PLEASE DO FORGET #1
DO (1) NEXT

(3) DO (4) NEXT
PLEASE GIVE UP

(4) DO (8) NEXT
DO ,9SUB#1 <- #176
DO ,9SUB#2 <- #80
PLEASE DO READ OUT ,9
DO .6 <- .8
DO .1 <- .5
DO .2 <- #1
DO (1010) NEXT
DO .5 <- .3
DO .1 <- '.5~.5'~#1
PLEASE DO FORGET .1
DO RESUME #1

(8) DO (5) NEXT

(5) PLEASE DO (6) NEXT
PLEASE DO FORGET #1
DO (5) NEXT

(6) PLEASE DO (7) NEXT
DO RESUME #2

(7) DO (10) NEXT
DO .1 <- .6
DO .2 <- #1
PLEASE DO (1010) NEXT
DO .6 <- .3
DO .1 <- '.6~.6'~#1
PLEASE DO FORGET .1
DO RESUME #1

(10) DO (11) NEXT
DO (13) NEXT
DO (14) NEXT
DO (15) NEXT

(11) DO (111) NEXT
DO (112) NEXT

(13) DO (113) NEXT
DO (112) NEXT

(14) DO (114) NEXT
DO (112) NEXT

(111) DO .1 <- .6
DO .2 <- .8
DO (1010) NEXT
DO .1 <- '.3~.3'~#1
PLEASE DO FORGET .1
DO RESUME #1

(112) DO ,9SUB#1 <- #142
DO ,9SUB#2 <- #114
PLEASE DO READ OUT ,9
DO RESUME #3

(113) DO .1 <- .6
DO .2 <- #1
DO (1000) NEXT
DO .1 <- .5
DO .2 <- .3
DO (1010) NEXT
DO .1 <- '.3~.3'~#1
PLEASE DO FORGET .1
DO RESUME #1

(114) DO .1 <- '.6~.6'~#1
PLEASE DO FORGET .1
DO RESUME #1

(15) DO ,9SUB#1 <- #252
DO ,9SUB#2 <- #4
PLEASE DO READ OUT ,9
DO RESUME #2


Goodness gracious. This took me a bit to figure out. The label numbers are a mess and therefore reflect that. I'm not going to try to explain this unless someone asks.

## Task 3

DO WRITE IN .5
DO WRITE IN .6

DO (1) NEXT

(1) PLEASE DO (3) NEXT
DO FORGET #1
DO (1) NEXT

(3) DO (4) NEXT
DO READ OUT .5
PLEASE GIVE UP

(4) DO .1 <- .5
DO .2 <- .6
PLEASE DO (1040) NEXT
DO .1 <- .3
DO .2 <- .6
PLEASE DO (1039) NEXT
DO .2 <- .3
DO .1 <- .5
DO (1010) NEXT
DO .5 <- .6
DO .6 <- .3
DO .1 <- '.6~.6'~#1
PLEASE DO FORGET .1
DO RESUME #1


This one's a tad simpler. Because of INTERCAL's...weirdness, you have to enter the numbers like this:

THREE FIVE


For instance, to get the GCD of 42 and 16, I'd enter:

FOUR TWO
ONE SIX


It also prints the number in Roman numerals...because that's INTERCAL for you!

2Shouldn't it be 1972? (I can understand if you're a bit dizzy after writing this :P) Your answer is considered invalid due to this mistake, which would be a shame. – marinus – 2015-04-28T21:15:08.693

@marinus Thank you! Fixed! – kirbyfan64sos – 2015-04-28T21:35:29.183

5PLEASE DO explain. (When you have time, of course. ;) – DLosc – 2015-05-02T05:18:08.990

1INTERCAL is my favourite language that I've never learnt! – CJ Dennis – 2015-05-02T11:59:10.737

1PLEASE GIVE UP. I did it already .-. – RedClover – 2017-12-29T18:18:24.483

24

# 1967 - APL

In 1957, at Harvard University, Ken Iverson started developing a mathematical notation for array manipulation. During the 1960s, his notation was developed into a programming language at IBM. The first partial implementation was created in 1963, and it was even used in a high school to teach students about transcendental functions. A full, usable implementation had to wait until 1965. For two years it was only used internally by IBM. In 1967, IBM released to the public an APL interpreter that ran on the IBM 1130 computer, which had been finished in 1966. You can understand how it's a bit hard to choose a year for it, however, I think it should be 1967, as this is the first year a full implementation was made available to the public. If anyone really disagrees, I could change it.

The source code for APL\360, is online, as is an emulator. This is what I have used to test these examples. It dates from 1967, and along with APL\1130 (for the aforementioned IBM 1130) it is more or less the true original. As expected, it is very primitive. It lacks support for such niceties as lowercase letters, any operators only work with builtin functions, and the set of builtin functions is very sparse (in particular, ∨ is only or, and does not double as gcd). The original, full description is available here, however, I noticed that the version I had is not even complete with respect to that document, lacking ⍎ among others.

I have provided the programs both in Unicode format (so you can read them), and in the original encoding (so you can cut and paste them into the emulator's APL window).

Unbelievably, these programs run correctly without any changes (except for the encoding) in modern versions of Dyalog, NARS2000, and GNU APL. So I guess I've found the way to write portable APL: just pretend it's 1967!

### Task 1:

Unicode:

⎕←'APL WAS MADE IN 1967!'


APL\360:

L[Kapl was made in 1967ÝK


### Task 2:

Unicode:

⎕←' N'[1+((2⍴N)⍴(⍳N)∊1,N)∨(⍳N)∘.=⍳N←⎕]


APL\360:

L[K nK;1-::2Rn"R:In"E1,n"(:In"J.%In[L'


### Task 3:

I have solved this the standard recursive way. In theory, you could do something clever and array-oriented, like the J answer; in practice, however, that has O(N) memory usage and quickly overwhelms Flower-Power-era hard- and software.

Unicode:

∇R←A GCD B
R←A
→(B=0)/0
R←B GCD B|A
∇

⎕←⎕ GCD ⎕


APL\360:

Gr[a gcd b
r[a
{:b%0"/0
r[b gcd bMa
G

L[L gcd L


This is awesome. – Alex A. – 2015-05-11T00:23:00.977

23

# 2005 - Prelude

Prelude is a very fun language, whose source code consists of several "voices" which are executed in parallel and which I really enjoy solving problems in. It is meant to be the ASCII representation of its sister language Fugue, which actually takes .midi files as its source code and encodes the instructions found in Prelude as intervals in the melodies of the voices.

Prelude is fairly minimalistic, yet Turing complete (provided you are using at least 2 voices). As I said, the voices (lines of code) are executed simultaneously, column by column. Each voice operates on its own stack, which is initialised to an infinite number of zeroes. Prelude supports the following instructions:

0-9 ... Push the corresponding digit.
+   ... Add the top two numbers on the stack.
-   ... Subtract the top number from the one beneath.
#   ... Discard the top of the stack.
^   ... Copy the top value from the voice above.
v   ... Copy the top value from the voice below.
?   ... Read a number and push it onto the stack.
!   ... Print the top number (and pop it from the stack).
(   ... If the top of the stack is zero, jump past the matching ')'.
)   ... If the top of the stack is zero, jump to the column after the matching '('.


Some additional notes:

• The voices are cyclic, so ^ on the top voice copies from the bottom voice (and vice versa).
• Multiple ? and ! in the same column are executed top to bottom.
• As per the language specification, ? and ! read and write characters with the corresponding character code. However, the Python interpreter also has a switch in its code to print the numbers themselves instead. For testing purposes I am actually using a modified version which can also read numbers instead of characters. But consensus around here is that numerical input/output can actually be given as byte values, hence these modifications are not necessary to make valid programs dealing with numbers.
• Matching ( and ) do not need to be on the same voice. The voice used for the condition is always the one where the ( appears. Hence, the vertical position of the ) is completely irrelevant.
• Due to the nature of Prelude's simultaneous execution, any instruction in the same column as a ( is executed only once before the loop starts, and regardless of whether the loop is entered. Similarly, any instruction in the same column as a ) is executed at the end of each iteration, regardless of whether the loop will be exited after this iteration.

I'll first show you the three programs without much commenting. You can find extensive explanations below.

## The Programs

### "Hello, World!" Variant

9(1-)v98+^++!9v+!  v88++2+!^  ! ^9-3-! v      !    v2-!55+!
8 8+ !     7v+! 1v+!88+^+!^4-!^ v8-^ !!!9v+  !^9+9+!  v5+!
^98++4+! ^8-! ^4-   ^ #!^6-!    ^^  #5+! v    ^2-!1+!


If you are using the Python interpreter, make sure that NUMERIC_OUTPUT = False.

### ASCII Art N

      v2-(1-)v
9(1-)?1-( v!  (1-55+!      0     (0)#  ))55+!
4-4+                  v^-#
v!      v! v1-v!(1- ^(#^!0)# v! )v!
6 8+           v#


For ease of use, this program benefits from reading input as numbers, but output must not be numeric. So if you are using the modified Python interpreter, set

NUMERIC_INPUT = True
NUMERIC_OUTPUT = False


### GCD

?(                         v)
? (^-(0 # v   #       ^+0)#^ !
^^ (##v^v+)#  0 (0 )
1) ^ #  - 1+(#)#


This is best used with all numeric input/output i.e.

NUMERIC_INPUT = True
NUMERIC_OUTPUT = True


## Explanations

### "Hello, World!" Variant

This is fairly straight-forward. I'm using 3 voices to successively generate the character codes for all the characters in Prelude was made in 2005!. I start by computing 8 + 9*8 = 80, which is the character code of P:

 9(1-)
8 8+


After that I mostly just copy the previous character code and add or subtract the difference to the next one. Here is the code, but with each ! replaced with the character that is being printed (and _ for spaces and % for the digits):

9(1-)v98+^++r9v+u  v88++2+w^  _ ^9-3-a v      _    v2-%55+!
8 8+ P     7v+l 1v+e88+^+_^4-s^ v8-^ de_9v+  n^9+9+%  v5+%
^98++4+e ^8-d ^4-   ^ #a^6-m    ^^  #5+i v    ^2-%1+!


The final 55+! prints a trailing newline, just because it's nicer.

As a side note, the number of voices is pretty arbitrary for this task, but 3 is fairly convenient because it's the largest number in which every voice can directly access each other voice.

### ASCII Art N

      v2-(1-)v
9(1-)?1-( v!  (1-55+!      0     (0)#  ))55+!
4-4+                  v^-#
v!      v! v1-v!(1- ^(#^!0)# v! )v!
6 8+           v#


With 5 voices, this is definitely one of the most complex programs I've written so far. The voices roughly have the following purposes:

1. Merely a helper voice which stores N-1 for use in the inner loop.
2. This is sort of the "main" voice, which reads input, contains an important switch and also contains the outer loop (i.e. the one over the rows).
3. This stores a 32 to conveniently print spaces.
4. This contains the inner loop (the one over the columns).
5. This stores a 78 to conveniently print Ns.

Let's go through the code part by part. First, I'm creating the 32 as -4 + 9*4 and the 78 as 6 + 9*8:

9(1-)
4-4+

6 8+


Now I'm printing a single N (because we always need one) while reading the input N and storing N-1 and N-2 in the first two voices:

      v2-
?1-

v!


Next, there is a "loop" conditioned on N-1. At the end of the loop, the second voice is always reduced to 0, and the loop exits after the first iteration. So essentially, this only if(N > 1){...}. After the loop we print a single trailing newline. To recap, we've now got the following framework:

      v2-
9(1-)?1-(                               )55+!
4-4+
v!
6 8+


Inside this conditional, we first N-2 spaces and a single N to complete the first row, and we also store N-1 on the first voice for future use:

         (1-)v
v!

v!


Now the real meat of the code. First, there is an outer loop, which prints N-1 rows. For each row, we first print a newline, and an N. Then we loop N-2 times, printing either spaces or Ns (more on that later). And finally we print another N:

               1-55+!

v1-v!(               )v!
v#


Finally, the fun part: printing each row (and getting the position of the N right). There is not really an if/else in Prelude, so I have to build it myself using two loops on different voices. The condition can easily be obtained by subtracting the inner and outer loop variable - we get 0 if we want to print N and something non-zero if we want to print a space.

The basic idea of an if/else in Prelude is to put a loop after the relevant value - the "if" (or non-zero) code, and exit it immediately by pushing a 0. On another voice, you keep a non-zero value, and another loop after the "if" loop. During the "if" loop you put a zero on top of that other voice, so as to prevent the "else" from being executed. There is some flexibility in whether you push zero values on top of non-zero values or simply discard the non-zero value if there's a zero beneath, but this is the general idea. You might also have to do some cleanup afterwards, if you want to keep using the relevant voice. This is what the code looks like:

                           0     (0)#
v^-#
1- ^(#^!0)# v!


And that's it!

### GCD

This is "just" an iterative implementation of the Euclidean algorithm. But modulo in Prelude is a bit annoying, mostly because you can't easily check if a number is positive or negative. This code makes use of a signum implementation I wrote a while ago. I.e. a large part of the code just turns a number into -1, 0 or 1. This can then easily be turned into a condition for positive or negative numbers by adding or subtracting 1.

?(                         v)
? (^-(0 # v   #       ^+0)#^ !
^^ (##v^v+)#  0 (0 )
1) ^ #  - 1+(#)#


So we've got four voices this time. The first voice simply keeps track of b and contains the main termination condition (i.e. the loop exits when b becomes 0). The second voice contains a and with the help of voices three and four computes a % b, before swapping the result with the previous b. Finally, the ! prints a when b == 0.

Let's look at the signum part first:

     (0 # v   #
^^ (##v^v+)#
1) ^ #  -


The input number n is found on the first of those voices (the second voice in the full program). The result will end up on the bottom voice. The other two voices are expected to be empty (i.e. filled with zeroes). Notice that, if n == 0, then both loops are skipped and the bottom voice still contains 0, just what we want.

If n is non-zero, the first small loop is entered. We push a zero to exit it immediately, put two copies of n onto the middle voice and a 1 onto the bottom voice. Now the basic idea is to increment one of the copies of n while decrementing the other copy of n until one of them hits zero. While doing so, the 1 on the bottom voice flips its sign all the time (which is easily done by subtracting it from 0 beneath it on the stack). This is set up such that when one of the numbers hits zero, the bottom voice will contain the correct sign.

Now modulo is implemented by subtracting b from a until the result is negative. When that happens, we add one b again. That's this bit:

  (^-  signum         ^+0)#
signum      0 (0 )
signum   1+(#)#


Notice the if/else construction at the bottom, which is similar to the one I used for Task 2.

2This should really be part of a Prelude tutorial. – Alex A. – 2015-05-06T20:37:43.480

22

# 1996 - Ocaml

Was waiting more than day to someone fill 1996, so I could fill in Ruby. Well why not learn OCaml then, seems similar to haskell...

# Hello world

print_endline "OCaml was made in 1996!";;


# ASCII

let ascii n =
let rec ascii' = function
| 0 -> ()
| i ->
let s = "N" ^ String.make (n-2) ' ' ^ "N" in
String.fill s (n-i) 1 'N';
print_endline s;
ascii' (i-1)
in ascii' n;;


Mutable strings!

# GCD

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


No == and infix mod, that's cute

I'm sorry, I filled in Ruby :) – Zero Fiber – 2015-04-14T12:14:46.603

4+1 for learning a language just to answer this challenge. :) – Alex A. – 2015-04-14T15:45:01.903

You just learned F#, too! (it's OCaml on the CLR plus some extras). – Robert Fraser – 2015-04-29T03:26:36.653

21

# 2007 - Scratch

Scratch is a language made by MIT for educational purposes. I've been very involved with it for 5 years; more on that later.

All of these can be viewed here.

I'm very rushed right now and will explain the snippets later. Hopefully they're prety self-explanatory though.

## Task 3

Is it later yet? – dfeuer – 2019-03-14T21:02:22.553

21

# 1972 - C

We all know about C, don't we? C was created at Bell Labs, along with Unix. Unix was largely written in C. All modern Unix derivatives are still largely written in C. C's syntax has influenced many, many programming languages. It is probably the oldest programming language that is still in widespread use for new development.

C itself is a descendant of B, which I hope will end up in this list as well. There was no 'A' programming language: B is a variant of BCPL, which in turn is a stripped down CPL. None of these languages were ever very popular. However, BCPL was the language in which the first "Hello World" program was written. Another interesting fact is that B had both /* */ and // comments, but C dropped the // comments. They were later reintroduced into C with the C99 standard.

The C programs here were tested with the Unix V5 C compiler, from 1974. This was the oldest C compiler I could find and get to work, and these programs will not compile on a modern C compiler. (One of the changes made is that mutation operators like += used to be written =+.)

#include <...> did not exist yet. Neither did much of the standard library. I had to write my own atoi. I went through some of the V5 source code to figure out which things were allowed and which were not. The version I used was the first to include structs, but since I did not use those, and the syntax doesn't seem to have changed a lot until V7 (as K&R C), this might work with earlier versions as well.

I have done my best to write my code in the same style as the V5 source code uses. (Not that that is terribly consistent, though.)

Look here for links to Unix V5, an emulator, and instructions on getting it running on a modern computer.

### Task 1

main()
{
write(1, "C was made in 1972!\n", 20);
}


### Task 2

atoi(str)
char *str;
{
register num, digit;
while (digit = *str++) {
num =* 10;
num =+ digit - '0';

}
return num;
}

N(n)
{
register x, y;
for (y=1; y<=n; y++) {
for (x=1; x<=n; x++) {
write(1, " N"+(x==1||x==y||x==n), 1);
}
write(1, "\n", 1);
}
}

main(argc, argv)
char *argv[];
{
N(atoi(argv[1]));
}


### Task 3

atoi(str)
char *str;
{
register num, digit;
while (digit = *str++) {
num =* 10;
num =+ digit - '0';
}
return num;
}

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

main(argc, argv)
char *argv[];
{
printf("%d\n", gcd(atoi(argv[1]), atoi(argv[2])));
}


Wow, I never realized how much C has changed... Where did you get that compiler from? – kirbyfan64sos – 2015-04-29T15:22:26.520

1

The compiler is the one included with Unix V5. There's a link in the description to a blog post that shows you where to get the files and how to run it on a modern computer. (It's here). Once you have it running, you can get the code onto it using cat > file.c. (End with Ctrl-D, as always). Also, C has changed less than you might think: if you swap the =* and =+ in the atoi functions for the modern equivalents *= and +=, a modern GCC will compile them just fine and they run, too. Hardly any warnings, even.

– marinus – 2015-04-29T15:36:47.500

2http://minnie.tuhs.org/cgi-bin/utree.pl?file=V2/c is the earliest C compiler I could find (from V2, dated '72). – Oberon – 2015-05-11T14:23:13.360

20

# 2009 - Idris

Idris is a dependantly-typed, pure functional language that emphasises being in fact practically usable for real-world applications, apart from offering the extremely rigorous proof possibilities that are achievable with dependant types.

## Task 1

module Main

main : IO ()
main = putStrLn "Idris was made in 2009!"


## Task 2

module InN

import Data.Fin
import Data.Vect

genN : Vect n (Vect n Char)
genN = [[ if inN x y then 'N' else ' ' | x<-range ]| y<-range ]

||| Helper function, determines whether the char at coordinate (x,y)
||| is part of the letter:
inN : Fin n -> Fin n -> Bool
inN {n=S _} x y = x==0 || x==y || x==last


This one is not a program but just a function (more precisely, dependant value), producing the desired letter N as a two-dimensional array.

$idris ascii-n.idr ____ __ _ / _/___/ /____(_)____ / // __ / ___/ / ___/ Version 0.9.17.1- _/ // /_/ / / / (__ ) http://www.idris-lang.org/ /___/\__,_/_/ /_/____/ Type :? for help Idris is free software with ABSOLUTELY NO WARRANTY. For details type :warranty. Type checking ./ascii-n.idr *ascii-n> genN {n=4} [['N', ' ', ' ', 'N'], ['N', 'N', ' ', 'N'], ['N', ' ', 'N', 'N'], ['N', ' ', ' ', 'N']] : Vect 4 (Vect 4 Char)  ## Task 3 module gcd gcd' : Nat -> Nat -> Nat gcd' a Z = a gcd' a b = gcd' b$ amodb


Note that I had to choose the name gcd' because as gcd it is already defined in the Idris prelude.

Type checking ./gcd.idr
*gcd> gcd' 8 12
4 : Nat
*gcd> gcd' 12 8
4 : Nat
*gcd> gcd' 234 876
6 : Nat


That looks like they took Haskell, swapped : and ::, and changed _ to Z. – wchargin – 2015-04-11T21:22:29.227

@WChargin Z is actually the constructor of 0 : Nat. The underscore is used in Idris just like it is in Haskell. – ceased to turn counterclockwis – 2015-04-11T23:45:48.410

oh, well, there you go! :) – wchargin – 2015-04-12T00:05:04.760

19

# 2014 - Pyth

Since we have CJam, we might as well also have Pyth for completeness :)

Pyth is a golfing language by @isaacg which compiles down to Python. It's notable for being procedural and for using prefix notation. Pyth first appeared around June 2014.

# "Hello, World!" Variant

"Pyth was made in 2014!


Note the lack of a closing quote, which is optional if a Pyth program ends in a string.

# ASCII Art N

VQ+\Nt+P++*Nd\N*t-QNd\N


Try it online. The equivalent Python is:

Q = eval(input())
for N in range(Q):
print("N"+((" "*N+"N"+(Q-N-1)*" ")[:-1]+"N")[1:])


Or expanded (the first and third lines are implicit):

Q = eval(input())                                        #
for N in range(Q):                                       #   VQ
print(                                          )    #
"N"+                                           #     +\N
(                                )[1:]     #        t
+"N"          #         +              \N
(                     )[:-1]              #          P
+(Q-N-1)*" "                    #           +      *t-QNd
+"N"                                #            +   \N
" "*N                                    #             *Nd


# GCD

=GvwWQAGQ,Q%GQ)G


This program uses the Euclidean algorithm, and takes two numbers separated by a newline. Try it online.

Q = eval(input())     #
G = eval(input())     #    =Gvw
while Q != 0:         #        WQ
G, Q = Q, G % Q     #          AGQ,Q%GQ)
print(G)              #                   G


i.uQ is even shorter if we use the builtin for GCD. This is equivalent to print(gcd(*eval(input()))) (taking two comma-separated numbers as input).

Drat - I was going to do Pyth xP – theonlygusti – 2015-04-06T12:52:06.537

@isaacg I can't help but wonder, and might as well ask it here: was pyth inspired by pyg in any way, shape or form? – ɐɔıʇǝɥʇuʎs – 2015-04-20T18:37:10.097

@ɐɔıʇǝɥʇuʎs I had seen PYG before making Pyth, and it might have influenced the 1 character - 1 concept approach. However, if anything inspired Pyth it was probably golfscript. – isaacg – 2015-05-06T23:17:28.870

19

# 1962 - SNOBOL

The "StriNg Oriented and symBOlic Language". At first apparently called the Symbolic Expression Interpreter, 'SEXI', which then had to be changed to prevent the 1960-s era nerds from blushing when submitting their jobs. True story.

This was one of the first languages that could deal with strings and patterns natively. Indeed, the first version of SNOBOL had the string as its only datatype. Math was then done by parsing. The initial implementation was done on the IBM 7090. It seems to be long gone, at least, I couldn't find it. What I did find was the original paper describing it as well as a SNOBOL3 interpreter in Java, which can run on a modern computer.

The first SNOBOL had pretty much only pattern matching and basic arithmetic. SNOBOL 3 then added functions and changed the I/O, but otherwise seems to have remained backwards compatible. SNOBOL 4 changed the syntax, and from there it developed into Icon, which keeps the pattern matching but almost looks like a "normal" programming language otherwise.

The programs I have written use only functionality described in the original paper, so should work with the original SNOBOL with the exception of the I/O, which I did in SNOBOL3 style so that the Java interpreter could run them. From the paper, it seems that the difference is that SNOBOL1 uses pattern matching with a special SYS variable, whereas SNOBOL3 uses input and output variables:

• Input:
• 1 SYS .READ *DATA*
• 3 DATA = SYSPPT
• Output:
• 1 SYS .PRINT 'A STRING' AND VARIABLES
• 3 SYSPOT = 'A STRING' AND VARIABLES

Making these substitutions should get you 'real' SNOBOL 1. Of course, then you can't run it.

## Task 1

START   SYSPOT = 'SNOBOL WAS MADE IN 1962!'


## Task 2

This shows math, string handling and flow control. SNOBOL3 has useful functions, like EQ to check equality; the original SNOBOL did not, so I haven't used them.

* READ N FROM INPUT
START   SYSPOT = 'SIZE?'
SZ = SYSPPT

* INITIALIZE
CS = ''
ROW = '0'

* OUTPUT PREVIOUS ROW AND START NEXT ONE
ROW     COL = '0'
SYSPOT = CS
CS = ''

COL     SUCC = 'N'
EQ1 = COL
FAIL = 'CHKE'
EQ2 = '0'         /(EQUAL)
CHKE    FAIL = 'CHKR'
EQ2 = SZ - '1'    /(EQUAL)
CHKR    FAIL = 'SPACE'
EQ2 = ROW         /(EQUAL)

* CONCATENATE THE RIGHT CHARACTER TO THE CURRENT LINE
SPACE   CS = CS ' '       /(NEXT)
N       CS = CS 'N'       /(NEXT)

* FOR NUMBERS, SUBSTRING MATCH IS ENOUGH IF IT IS KNOWN A<=B
NEXT    COL = COL + '1'
COL SZ            /F(COL)
ROW = ROW + '1'
ROW SZ            /F(ROW)S(FIN)

* THERE SEEMS TO BE NO EQUALITY CHECK, JUST SUBSTRING MATCHING
* OF COURSE, EQ1 == EQ2 IFF EQ1 CONTAINS EQ2 AND VICE VERSA
* THIS ALSO ILLUSTRATES INDIRECTION
EQUAL   EQ1 EQ2           /F($FAIL) EQ2 EQ1 /S($SUCC)F($FAIL) * OUTPUT THE LAST LINE FIN SYSPOT = CS  ## Task 3 First, the boring one. The only thing of note is the smaller-than check, showing exactly how string-oriented SNOBOL really was: (B - A) '-' means "does the result of B-A contain a minus?". SNOBOL3 can also do LE(B,A), but SNOBOL 1 could not (at least the paper doesn't mention it). * READ A AND B START SYSPOT = 'A?' A = SYSPPT SYSPOT = 'B?' B = SYSPPT * GCD LOOP STEP '0' (A - B) /S(DONE) (B - A) '-' /S(AB)F(BA) AB A = A - B /(STEP) BA B = B - A /(STEP) DONE SYSPOT = 'GCD: ' A  Of course, when you have a language based entirely around strings and pattern matching, it would be a shame not to actually get to use the pattern matching and replacement. Thus, here is one of those unary-based GCDs, including routines for converting to and from unary. * READ A AND B START SYSPOT = 'A?' A = SYSPPT SYSPOT = 'B?' B = SYSPPT * CONVERT TO UNARY UNA.IN = A UNA.FIN = 'ADONE' /(UNA) ADONE A = UNA.R UNA.IN = B UNA.FIN = 'BDONE' /(UNA) BDONE B = UNA.R * USE STRING MATCHING TO FIND GCD STEP '' B /S(GDONE) MATCH A B = /S(MATCH) C = B B = A A = C /(STEP) * CONVERT BACK TO DECIMAL GDONE DEC.IN = A DEC.FIN = 'DONE' /(DEC) DONE SYSPOT = 'GCD: ' DEC.R /(FIN) ***************************** * DECIMAL TO UNARY SUBROUTINE UNA UNA.R = UNA.DGT UNA.IN *.DGT/'1'* = /F($UNA.FIN)
.X = UNA.R
UNA.R =
UNA.MUL .X *.Y/'1'* =              /F(UNA.ADD)
UNA.R = UNA.R '##########' /(UNA.MUL)
UNA.ADD '1' .DGT                   /S(UNA.1)
'2' .DGT                   /S(UNA.2)
'3' .DGT                   /S(UNA.3)
'4' .DGT                   /S(UNA.4)
'5' .DGT                   /S(UNA.5)
'6' .DGT                   /S(UNA.6)
'7' .DGT                   /S(UNA.7)
'8' .DGT                   /S(UNA.8)
'9' .DGT                   /S(UNA.9)
'0' .DGT                   /S(UNA.DGT)
UNA.1   UNA.R = UNA.R '#'          /(UNA.DGT)
UNA.2   UNA.R = UNA.R '##'         /(UNA.DGT)
UNA.3   UNA.R = UNA.R '###'        /(UNA.DGT)
UNA.4   UNA.R = UNA.R '####'       /(UNA.DGT)
UNA.5   UNA.R = UNA.R '#####'      /(UNA.DGT)
UNA.6   UNA.R = UNA.R '######'     /(UNA.DGT)
UNA.7   UNA.R = UNA.R '#######'    /(UNA.DGT)
UNA.8   UNA.R = UNA.R '########'   /(UNA.DGT)
UNA.9   UNA.R = UNA.R '#########'  /(UNA.DGT)

*****************************
* UNARY TO DECIMAL SUBROUTINE
DEC     DEC.R =

# Task 2

Define the function ascii-art() :

=(ascii-art
'( =(*  x   #(2- $(_1)) I I( *($(x) " ") N)
foo '( #(. #(I $(x))) )) #(say ?( #(==$(_1) 1) N "N#(map foo #(.. 1 $(_1)))N" )) ))  Ascii-art()'s shortest working form (88 bytes) : =(f'(=(* x#(2-)I I(*($(x)" ")N)g'(#(.#(I$(x)))))#(say?(#(==$(_1)1)N"N#(map g#(..))N"))))

• =(var val...) is the MuffinMC macro command to define a variable, or reassign it.

• $(var) is the MuffinMC macro command to access a variable's value. It naturally accepts the form $(v1 v2 ...) to access many variables at once.

• =(* var1 val1 var2 val2 ...) is the extension of MuffinMC macro command =(...) to deal with parallel assignments.

• Variables _1, _2, ... are dynamically scoped (shallow binding mechanism) and automatically set to bind to the function's arguments. Borrowed from Perl5, system variables # (number of arguments) and @ (list of arguments) are also automatically set.

• Functions are simply variables bound to any number of MuffinMC statements.

This interesting solution comes from combining two natural MuffinMC built-in features :

1. The MuffinMC I(...) macro command, to define cycling-iterators, later used with the functional form #(my-iterator want-number-of-values),

2. The MuffinMC string-product construct, an extension of the natural variable interpolation, which, given any string "F1 F2 F3...", where the Fis are either MuffinMC string literals or MuffinMC macro command (aka functional forms), will produce as many strings as given by the product cardinal(F1) x cardinal(F2) x ... .

For instance, given x a variable that holds 2 values, says a and b, and y another variable that holds 3 values, says, 1 2 3, then the evaluation of the string "x=$(x) y=$(y))" will produce 6 different values, namely, in that order :

• "x=a y=1"
• "x=a y=2"
• "x=a y=3"
• "x=b y=1"
• "x=b y=2"
• "x=b y=3"

This is one of MUTINY project's highly desirable features MuffinMC was designed for.

Run it !

#(ascii-art 1)

N

#(ascii-art 3)

N N
NNN
N N

#(map '( #(ascii-art $(_1))) 5 7 9) N N NN N N N N N NN N N N N NN N N N N N N N N N N N NN N N N N NN N N N N N N N N N N N N N N N N N NN N N  ### How does it work Our algorithm is based on the followings: Given a call to ascii-art(n), {n = 2p+1 | p integer, p>= 0}, the art to generate comprises n strings of n characters, amongst which, two, the leftest and rightest, are fixed and always the same : 'N'. This allows to reduce the problem in producing only the middle strings. For instance, given n=5, we would weed to produce the 5 following middle strings, each made of n-2 characters (we have replaced the space by a '_' for the sake of better visualization) :  The 5 strings : _ _ _ N _ _ _ N _ _ _ N _ _ _ can be seen as resulting from splitting in groups of 3 characters the following infinite sequence of 4 characters : /---- < _ _ _ N > ----\ | | \---------------------/ which, once unfolded, yields the infinite ruban : _ _ _ N _ _ _ N _ _ _ N _ _ _ N _ _ _ N _ _ _ N ... ^ ^ ^ ^ _ _ _ | | | | N _ _ | | | _ N _ | | _ _ N | _ _ _  • Such middle strings can easily be produced by cycling over the 4 elements sequence ('_' '_' '_' 'N') in 5 groups of 3 ; given n, the function's input, such sequence is made of n-2 characters '_', followed by the character 'N'. Cycling over this sequence requires nothing else but embedding the sequence within a MuffinMC I(sequence) built-in iterator (an iterator that cycles forever over its initial sequence of values). • We then simply produce the middle strings, of length n-2, by asking our iterator to give us its next n-2 values (n - 2 characters), which are concatenated together to produce the expected middle string. • The n middle strings are produced by repeating n times the above process, using a map to collect the n results (n strings of n-2 characters). • We use another powerful MuffinMC built-in construct, namely the string product, to produce the n final strings : "N#(map...)N". • And that's it ! Commented script =(ascii-art Define the 'ascii-art' variable to hold the function's definition. When called, its argument, the actual value of n, will be bound to the system variable _1, accessed as$( _1 ).

'(                         '(...) quote macro-command -- protects
its arguments, here the function
definition, from being evaluated.
We want to keep it literally for further evaluation.

=(*                     =(*...) // assignment macro-command.
Similar to the Lisp (let (...)...),
not the let* !

x #(2- $(_1)) Define the variable x to hold the value n-2. I I( Define I to be an iterator over the the x+1 characters sequence : *($(x) " ")   . x white-space characters
N              . 1 'N' character (here the atom N)
)

foo '(              Define the variable foo as a function
#(.          to catenate ( #(. s1...) )
#(I $(x)) the iterator's next x elements. ) ) ) End of =(*... #(say Print each element of: ?( If #(==$(_1) 1)        n equals 1
N                    the atom N,
"N#(map foo #(.. 1 $(_1)))N" else the n strings as a string-product resulting from foo-computing the ) n middle-strings. ) ))  # Task 3 Define the function gcd() : =(gcd '( ?( #(==$(_2) 0)
$(_1) #(self$(_2) #(mod $(_1)$(_2)))) ))


gcd()'s real shortest form (37 bytes - 2bytes gain thanks to Rodolvertice)

=(g'(?(#(z$(_2))$(_1)#(g$(_2)#(mod)))))  Run it ! #(gcd 225 81)  yields 9. That's it. Thank you for the nice game, and possibly for your interest. The language is available to any one who would like to play with, use it, or even extend it. Just ask for it and I will be glad to send it in. Cheers Franck PS. MuffinMC's current implementation is in Perl5. The source code is about 2000 lines of modern Perl, including comments, and it comes bundled with a non-regression test-suite, which is great to learn hands-on MuffinMC constructs and semantics. Really nice! The shortest form of the ascii-art has a shortened function name, but the GCD shortest doesn't. Is this intentional, because if it isn't you can shave off another 2 bytes. +1 – rodolphito – 2015-04-10T08:21:37.073 Sure, and it's intentional. Should I ? yes, let's do it ;) Thanks for the post, and your appreciation. – Franck Porcher – 2015-04-10T10:18:07.097 1Since you're trying to get rid of extra characters (and because I can be an incorrigible grammar-nasty), you could (should) remove the space in front of the exclamation mark for the first task. That space is correct in French afaik, but not in English. – Amos M. Carpenter – 2015-05-05T06:58:49.117 15 # 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: 14 # 2010 - Rust Rust is a general purpose, multi-paradigm, compiled programming language developed by Mozilla Research. It is designed to be a "safe, concurrent, practical language", supporting pure-functional, concurrent-actor, imperative-procedural, and object-oriented styles. Wikipedia # Task1 fn main() { println!("Rust was made in 2010!"); }  # Task2 fn main() { // get commandline arguments // "test 3" let args : Vec<_> = std::env::args().collect(); // convert 2nd argument to integer let n = u32::from_str_radix( args[1].as_ref(), 10 ).unwrap(); print_n( n ); } fn print_n( n: u32 ) { for y in range( 0, n ) { for x in range( 0, n ) { if x == 0 || x == y || x + 1 == n { print!("N"); } else { print!(" "); } } println!(""); } }  # Explanation: if x == 0 || x == y || x + 1 == n  takes care for printing only vertical ( left and right | ) and diagonal ( \ ) # Task 3 simple implementation of Euclidean_algorithm fn main() { // get commandline arguments // "test 453 3" let args : Vec<_> = std::env::args().collect(); // convert 2nd and 3rd argument to integers let a = u32::from_str_radix( args[1].as_ref(), 10 ).unwrap(); let b = u32::from_str_radix( args[2].as_ref(), 10 ).unwrap(); let g = gcd( a, b ); println!( "GCD of {} and {} is {}", a, b, g ); } fn gcd( mut a: u32, mut b: u32 ) -> u32 { while b != 0 { let c = a % b; a = b; b = c; } return a; }  Could you add a snippet showing how to input two space-seperated integers from the stdin? – Zero Fiber – 2015-04-08T13:48:36.707 3 Was Rust "made in" 2010? Timeline of programming languages says so, but the actual article says that it was only announced in 2010 (actually 2011 as evidenced by the reference) and that version 0.2 was released in 2012. – EMBLEM – 2015-04-08T14:40:37.813 1 @SampritiPanda, take look into http://hastebin.com/raw/lapekowogu – wasikuss – 2015-04-08T22:00:11.430 1Looks a bit modern-ish. Can it compile it the first <s>released</s> published working version of the compiler? – Vi. – 2015-04-13T22:00:53.257 14 # 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; }  14 # 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. I don't think first version of AWK had functions if https://www.gnu.org/software/gawk/manual/gawk.html#V7_002fSVR3_002e1 is to be believed. – Konrad Borowski – 2015-11-14T15:15:52.213 13 # 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)  1What happens if you say [indent=4] but you actually indent by 2 spaces? Does it break? – Sp3000 – 2015-04-09T11:40:39.107 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. – kuldeep.kamboj – 2015-04-09T11:59:44.790 13 # 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)..  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. – Ismael Miguel – 2015-04-09T18:37:09.203 @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. – Konrad Borowski – 2015-04-09T20:34:17.987 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. – Ismael Miguel – 2015-04-09T20:46:27.200 13 # 1985 - Dr. LOGO 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: 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 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. As a bonus, it can also output even sized patterns! # 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. 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! 3I 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. – ASCIIThenANSI – 2015-05-03T04:33:13.090 2I 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! – CJ Dennis – 2015-05-05T05:07:59.353 12 # 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); } }  2 According to Wikipedia, C# first appeared in 2000. – Zero Fiber – 2015-04-12T07:29:43.017 @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. – Alex A. – 2015-04-12T20:11:27.487 1Why would 2000 break everything? Is Y2K still a problem today? – ASCIIThenANSI – 2015-04-14T02:38:58.927 @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. – Alex A. – 2015-04-14T03:07:21.583 The ASCII Art programming will fail when n=1 because its not valid to construct a string of length -1. You may want to introduce an extra check to guard against this exceptional case. – pmarflee – 2015-04-26T12:52:22.173 @pmarflee: Thanks! Updated. Handled it in Main rather than in AsciiN. – Alex A. – 2015-04-26T19:37:13.117 2Too bad you're only allowed to use C# 1.0. Newer features really set C# apart. – Dennis_E – 2015-04-29T13:08:35.343 12 # 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. 1+1 for "JavaScript is like Java the way a car is like a carpet." – Amos M. Carpenter – 2015-05-05T05:44:59.810 1 @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. – Scimonster – 2015-05-05T06:16:39.433 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. :-) – Amos M. Carpenter – 2015-05-05T06:26:37.223 Worked now. When that happens to me it's usually because of an internet connectivity issue. – Scimonster – 2015-05-05T06:29:40.287 12 # 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. Should it not be if (zero? n) in the gcd? – VisualMelon – 2015-04-15T07:34:45.193 1 Isn't Racket just one of the 30+ implementations of Scheme? As in, Racket : Scheme = GCC : C – Tobia – 2015-04-20T21:34:35.837 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). – None – 2016-11-29T13:12:40.967 @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. – dfeuer – 2019-03-14T19:05:51.033 12 # 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  2Nice, +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. ;) – Alex A. – 2015-04-14T15:44:06.927 @AlexA. True I always forget (despite the fact that I campaigned to have r syntax highlighting on SE :) ) – plannapus – 2015-04-15T06:01:37.103 You're behind that magic? Thank you, I use it all the time! – Alex A. – 2015-04-15T14:21:56.200 12 # 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%  3...hence the origin of the term "spaghetti code" with abundant use of GOTO in large programs. – mbomb007 – 2015-04-22T21:33:18.557 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). – Rhialto supports Monica – 2017-07-05T19:37:49.970 12 # 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. 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. – Amos M. Carpenter – 2015-05-05T09:26:25.010 “Mother of all OO languages” **cough** – ceased to turn counterclockwis – 2015-05-05T17:57:28.083 1 @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. – Amos M. Carpenter – 2015-05-05T23:55:31.563 12 # 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 § 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! – Brian Tompsett - 汤莱恩 – 2015-09-01T21:57:55.383 11 # 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))  11 # 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)  11 # 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; }  11 # 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. 1J is based on function composition. It can even solve things like obverses (usually inverse) of functions. – seequ – 2015-04-12T18:20:59.943 @Sieg It's already 1990. You can write a J answer now. – alephalpha – 2015-04-15T02:25:51.433 11 # 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  11 # 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;  IMO, the æsthetics of Ada are in fact surprisingly elegant, given the language's origin. Better than Fortran, COBOL or Java at any rate... – ceased to turn counterclockwis – 2015-04-17T20:56:09.370 1@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. – marinus – 2015-04-17T22:10:25.887 The date of Ada 83 Reference Manual is January 1983 (not 1980). – scaaahu – 2015-11-08T13:08:49.457 11 # 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  @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. – MickyT – 2015-04-30T01:15:28.317 2Kudos 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! – CJ Dennis – 2015-05-02T11:44:45.880 1@CJDennis Have change the greeting. I wouldn't want to offend our mates downunder :) – MickyT – 2015-05-02T20:18:49.283 11 # 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. It's funny how they put auto back in C++11. – marinus – 2015-05-07T13:06:11.463 1@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. – Leushenko – 2015-05-07T13:17:22.657 Huh. Didn't know that. – marinus – 2015-05-07T13:33:06.093 1Note 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. – Mark – 2015-05-08T00:58:30.430 11 # 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!'>; }


$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>>; }


2PSA for all the language designers out there : Prout is an onomatopoeia for farts in french language. – Aaron – 2015-10-26T16:13:44.740

10

# 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)


GCD Was task 3 and N was task 2 – Optimizer – 2015-04-14T12:15:17.333

Putting <!-- language-all: lang-rb --> will invoke syntax highlighting for the code bits. – Alex A. – 2015-04-21T15:15:05.333

10

# 1993 - K

Can't believe I missed the year I was waiting for again. ARGH!

K is basically the result of squeezing APL into an ASCII character set and making it a bit more human.

K 3.0 contained several words to replace some of the symbols; that mode was renamed to Q.

These examples will use K 2.0, tested on Kona.

## Task 1

0:"K was created in 1993!"


## Task 2

ascii:{[n]{0::[(~x[1])|x[0]=x[1];"N";x[1]=n-1;"N\n";" "]}',/(!n),/:\:!n}
ascii[0$0:]  EDIT: Using the normal algorithm is boring; let's use matrices instead! ascii:{m::1!((2;x)#x#"N"),(x-2;x)#x#" ";{m[x;x]:"N"}'!x;{0:$x,"\n"}'+:[x=1;1#]m}
ascii[0$0:]  ## Task 3 gcd:{:[y;_f[y;x!y];x]} i:,/0: 0:$gcd[0$i;0$(i?" ")_ i]


10

# 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.


10

# 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++.

1You 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.) – Lynn – 2015-04-17T16:52:57.217

1@nooodl Darn, I think I'll change this to 1981 for C for Classes and say it was the first version... ;) – kirbyfan64sos – 2015-04-17T17:25:26.740

1

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.

– ceased to turn counterclockwis – 2015-04-17T19:35:14.500

@leftaroundabout Fixed. I based it on the examples from cfront in 1983. – kirbyfan64sos – 2015-04-17T20:49:03.807

9

# 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
{

### Task 1

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


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

### Task 2

<?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 http://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 – 2015-04-19T18:24:46.557

@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 – 2015-04-20T15:07:01.363

You missed an opportunity to do the screenshot in a 1995 browser :) – None – 2016-11-29T12:55:08.500

8

# 1990 - J

## Task 1: Hello World!

'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.

## Task 2: ASCII N

' 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


## Task 3: GCD

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.

8

# 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.

## Task 1

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


## Task 2

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


## Task 3

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


3It looks like it's Python's granddad. – marinus – 2015-04-25T09:13:31.000

Try clu2c.

– kirbyfan64sos – 2015-04-25T22:18:47.140

Nevermind; link's down. Oh well. +1 because you seriously saved all our hinds from 1974! – kirbyfan64sos – 2015-04-26T00:53:41.967

1

Actually, there's a working version here...but the build system's badly broken.

– kirbyfan64sos – 2015-04-26T01:01:34.313

8

# 1971 - dc

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

## Task 1

[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.

## Task 2 (ASCII art)

# 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

# Ask input
? 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.

8

# 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.

## Task 1

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!" ;


## Task 2

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 ;


## Task 3

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 .


4

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 – 2015-05-07T01:25:19.157

@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. http://codegolf.stackexchange.com/questions/48476/programming-languages-through-the-years/49701#comment116686_48476

– mbomb007 – 2015-05-07T15:38:24.550

@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 – 2015-05-07T15:42:02.560

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 – 2015-05-07T15:48:32.800

1@leftaroundabout Well, I read it as an upset-sounding comment. – mbomb007 – 2015-05-07T15:51:30.617

8

# 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.

# Task 1

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:

# Task 2

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
To read an integer
@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:

# Task 3

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!

7

# 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

# Task1

printfn "F# was made in 2005!"


# Task2

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 ( \ )

# Task 3

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 – 2015-04-10T12:06:28.687

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 – 2015-04-10T12:37:26.507

3

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 – 2015-04-10T12:43:52.443

@VisualMelon, I've never heard about Tail Recursion, good to know :) – wasikuss – 2015-04-10T13:04:35.543

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 – 2015-04-10T13:20:11.673

right, I rewrote code from Rust and I didn't check if it works same – wasikuss – 2015-04-10T13:29:50.927

7

# 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.

### Task 1:

>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.

### Task 3:

>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 – 2016-02-04T22:51:20.337 7 # 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.) ### Task 1 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. ### Task 2 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. ### Task 3 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. 7 # 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


### Task 3

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 – 2015-04-28T22:22:49.027

@kirbyfan64sos absolutely correct, thanks. – xebtl – 2015-04-29T08:25:37.330

Is using floating point deliberate in task 3? – CJ Dennis – 2015-05-02T15:54:27.217

@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. 971983991997967*937 = 854491261035335569 and one of its factors), so I changed the code to use integers. – xebtl – 2015-05-02T18:49:58.233

6

# 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. ;)

## Task 1

println "Felix was made in 2001!";


## Task 2

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;


6

# 2007 - GolfScript

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

### Task 1

;"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.

### Task 2

~: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.

### Task 3

~{.@\%.}do;


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

6

# 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.

### Task 1

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!";


### Task 2

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.

### Task 3

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.

6

# 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.

6

# 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. :)

## Task 1

MODULE print;

IMPORT Out;

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


## Task 2

    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.


## Task 3

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.


6

# 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.

## Task 3

### "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.

5

# 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?

### Task 1

echo zsh was made in 1990!


No quotes necessary.

### Task 2

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.

### Task 3

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). 5 # 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  4 # 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)


4

# 1989 - Bash

Bash (sometimes called Bourne Again Shell ) is famous unix/linux shell. It introduced by Brian cox for GNU Project in 1989. It practically default shell in most of linux distributions.

# Task 1

echo "Bash was made in 1989"


# Task 2

ascii() {
n=$1 i=0 while [$i -lt $n ]; do j=0 while [$j -lt $n ]; do v=$(($n-1)) if [ "$j" -eq "0" ] || [ "$j" -eq "$v" ] || [ "$i" -eq "$j" ]; then
echo -n "N"
else
echo -n " "
fi
j=$((j+1)) done echo "" i=$((i+1))
done
}

# Usage
ascii 5


# Task 3

gcd() {
a=$1 b=$2
retval=0
if [ "$a" -ne "$b" ]; then
if [ "$a" -gt "$b" ]; then
let large=$a let small=$b
else
let large=$b let small=$a
fi
while [ $small -ne 0 ]; do let m=$(($large %$small))
let large=$small let small=$m
done
retval=$large fi } # Usage gcd 8 12 echo$retval


Improved version of Task 3

gcd() {
a=$1 b=$2
retval=0
while [ $a -ne$b ]; do
if [ "$a" -gt "$b" ]; then
let a=$a-$b
else
let b=$b-$a
fi
done
retval=$a } gcd 8 12 echo$retval


Disclaimer : I have no manual/version to check if following code also work for initial versions.

Why not just the obvious solution? gcd() { if [ $2 == 0 ] ; then echo$1 ; else gcd $2$(($1 %$2)) ; fi } – marinus – 2015-04-17T18:41:06.323

4

# 2013 - Pyret

Pyret is a scripting language designed for educational purposes. It was created by the team behind Racket and has a Python-inspired syntax. It encourages programming in a functional style through features such as pattern matching and algebraic data types. Unit testing is a first-class feature of the language.

# Task 1 - Hello World

print("Pyret was made in 2013!")


# Task 2 - Ascii Art N

fun ascii_art_n(size):
if size == 1:
print("N")
else:
outer = "N" + string-repeat(" ", size - 2) + "N"
print(outer)
range(1, size - 1).each(
lam(row): print("N" + string-repeat(" ", row - 1) + "N" + string-repeat(" ", size - 2 - row) + "N")
end)
print(outer)
end
end


# Task 3 - GCD

fun gcd(a, b):
if b == 0:
a
else:
gcd(b, num-modulo(a, b))
end
end

print(gcd(8, 12))
print(gcd(12, 8))
print(gcd(3, 30))
print(gcd(5689, 2))
print(gcd(234, 876))


1Well, that can't possibly cause headaches, - as a valid character within names... – ɐɔıʇǝɥʇuʎs – 2015-04-28T13:45:21.527

2

@ɐɔıʇǝɥʇuʎs - From the Pyret Style Guide: 'Most languages can’t support dashes because the dash also stands for infix subtraction. In Pyret, subtraction must be surrounded by space. Therefore, camel-case is a name whereas camel - case is subtraction.'

– pmarflee – 2015-04-29T15:23:34.073

3

# 2008 - Nim

Nim (formally "Nimrod") is a statically typed, imperative programming language. It is designed as a modern systems programming language, combining runtime efficiency with an expressive syntax.

# Hello World!

No ceremony required here. We use the echo function from the system module that is automatically imported for all programs to write a message to stdout.

echo "Nim was made in 2008!"


# Ascii Art N

This program expects a single command-line argument that is the size of the letter N to produce. Nim's expressiveness is demonstrated by the use of list comprehensions to generate the list of values to enumerate over. stdout.write is used instead of echo so that a newline character is not written to stdout after printing each character.

from os import paramStr
from strutils import parseInt

let size = parseInt(paramStr(1))

for i in 1..size:
for j in 1..size:
if j == 1 or j == i or j == size:
stdout.write 'N'
else:
stdout.write ' '
stdout.write "\n"


The following statement, run from the console, will generate a letter N of size 10:

nim c -r ascii_art_n.nim 10


# GCD

Not much to say here. Note the use of the implicit variable result that is used to return a value from the function.

proc gcd(a: int, b: int): int =
if b == 0:
result = a
else:
result = gcd(b, a mod b)

echo gcd(8, 12)
echo gcd(12, 8)
echo gcd(3, 30)
echo gcd(5689, 2)
echo gcd(234, 876)


3

# 1993 - Excel VBA

Task 1

MsgBox "VBA was made in 1993!"


Task 2

 n = InputBox("Please enter n")
Cells(1, 1).Select
ActiveCell.Value = "N"
For i = 0 To n - 1
ActiveCell.Offset(i, i).Value = "N"
Cells(i + 1, 1).Value = "N"
Cells(i + 1, n).Value = "N"
Next


Task 3

x = InputBox("Please enter first integer")
y = InputBox("Please enter second integer")
Do While y <> 0
t = y
y = x Mod y
x = t
Loop
Gcd = x
MsgBox Gcd


You should probably add that you'll need references to an Excel object library for this to work. It's not standard across all VBA! – Mark Butler – 2015-09-09T14:20:59.250

2

# 2015 - Pip

Task 0:

Pip is fun. I just recently found out about it, but the first commits on github are from 2015. It was created by dloscutoff, who states that it exists to make golfing easier, and to that end it: "1) is imperative, and 2) uses infix operators"

Task 1:

"Pip was made in 2015"


Task 2:

b:qFa,b{Fc,b{(c=0|c=b-1|c=a)?O"N"Os}Ps}


Try it online!

Task 3:

a:qb:qWb{t:bb:a%ba:t}a


Try it online!

I might add explanations if I have time later. Fun question, thanks!

2

# 1998 - C++98

Bjarne Stroustrup created C++ after his work on the predecessor C with Classes which an extension of C and some other languages. In 1998, ISO standardised C++ and later released C++03 in 2003 with some bug fixes, but from a programmer's perspective there's little difference according to his FAQs:

http://www.stroustrup.com/bs_faq.html#C++03

Hello world

void H(){std::cout<<"C++ was made in 1998!\n";}


N in ACSII

void N(int n)
{
char x;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
x=' ';
if(j==0||i==j||j==n-1)x='N';
std::cout<<x;
}
std::cout<<std::endl;
}
}


GCD

void G(int x, int y)
{
int d=1,g=1;
int m=(x<y)?x:y;
do
{
g++;
if(x%(g)==0 && y%(g)==0)d=g;
}
while(g<=m);
std::cout<<d;}


Tests

#include <iostream>
int main()
{
H();
int n;
std::cin>>n;
N(n);
int a,b;
std::cin>>std::skipws>>a>>b;
G(a,b);

return 0;
}


Edit Fixed as suggested in comments

4

I'd suggest calling this C++98 because as is your language name is read as "Standard C++ C++ Wiki". It would also be best if you can explain a bit about how C++98 differs from other versions of C++ and if any of those differences are present in your code. Otherwise posting this 1998 standard of C++ doesn't mean much.

– Calvin's Hobbies – 2015-04-13T21:09:11.580

@Calvin'sHobbies what's wrong with it now? – bacchusbeale – 2015-04-14T02:56:57.963

3The std namespace and new header names like <iostream> are specific to Standard C++, which would be good to note in the answer. Speaking of the latter, this code has some problems, like missing #include directives, and main() declared as void (instead of int), which makes this code very much not Standard C++. – Bradd Szonye – 2015-04-16T01:35:53.303

1

# 2013 - Wren

Wren is a language invented in 2013. I am not sure why it is created, but as far as I can tell, the author says that it is a very lightweight language. As a result this is very fast; it can beat the speed of Lua.

I have nothing more to say, I'll just copy the sentences verbatim from the blogs.

# Hi Wren!

System.print("Wren was made in 2013!")


Try it online!

# ASCII Art

See, just one for loop will do this job!

Fn.new{ |N|
for(i in 1 .. N) {
var a = "N" +
" " * (i - 1) +
"N" +
" " * (N - i) + "N"
System.print(a.replace("NN","N").
replace("N " ,"N"))
}
}


Try it online!

# GCD

Unfortunately Wren does not support recursion. :( This uses iteration instead.

Fn.new{ |a, b|
var t

while(a % b != 0) {
a = a % b
t = a
a = b
b = t
}

return b
}


Try it online!

1

# 1987 - Erlang

The testing version of Erlang was released to the public on 1987.

Erlang is a multipurpose programming language designed for concurrency and distributed systems. It is designed to be easy to learn and use, and it's special for its error-tolerance.

## Task 1


main([]) -> io:fwrite("Erlang was made in 1987!").
% Just a boring fwrite of the string.


Try it online!

## Task 2


loop(A, 0) -> "";                         % Ending condition: If N is 0,
% exit the loop
loop(A, N) -> loop(A+1, N-1)              % Otherwise, prepend loop(A+1,N-1)
% to the following string:
++ "N"                         % Concatenate with string "N"
++ string:slice (              % Slice the following string:
string:copies(" ", N-1) % Repeat " " N-1 times
++ "N"                     % Append "N"
++ string:copies(" ", A),  % Repeat " " A times
1, A+N-2)                  % Remove the beginning & end
% of the string
++ "N~n".                      % Append "N" plus a newline
loop(N)    -> loop(0, N).                 % For the input number,
% get into the loop
main([])   -> io:fwrite(loop(7)).         % Test section


Try it online!

## Task 3

Nice & simple.


gcd(A, 0) -> A;                      % If B is 0, return A.
gcd(A, B) -> gcd(B, A rem B).        % Otherwise, return gcd(B, A%B).
main([]) -> io:write(gcd(234,876)).  % Test section


Try it online!

0

# 05AB1E - 2015

## "Hello, World!" Variant

0•5¶Ï•h«…€¥ƒ›€†Ž7ç'!«ðý


Try it online!

0•5¶Ï•h«…€¥ƒ›€†Ž7ç'!«ðý  # full program
«                 # join...
•5¶Ï•                   # 371486...
h                  # in hexadecimal...
«                 # with...
0                        # literal
…€¥ƒ›€†          # push "was made in"
«    # join...
Ž7ç       # 2015...
«    # with...
'!     # literal
ý  # join stack by...
ð   # spaces
# implicit output


## ASCII Art N

Θi'Nëð¹Í×'N©.ø¹<GðN<×®«ð¹N-Í×«®.ø}ð¹Í×®.ø}»


Try it online!

Θi'Nëð¹Í×'N©.ø¹<GðN<×®«ð¹N-Í×«®.ø}ð¹Í×®.ø}»  # full program
i                                           # if...
# implicit input...
Θ                                            # is 1...
'N                                         # push literal
ë                                        # else...
.ø                               # surround...
'N                                  # literal...
©                                 # (also store in register_c)...
.ø                               # with...
¹                                      # input...
Í                                     # minus 2...
ð  ×                                    # spaces
G                            # for N in [1, 2, ...,
¹                              # ..., input...
<                             # minus 1...
G                            # minus 1]...
.ø            # surround...
«               # joined...
«                      # joined...
N                          # variable...
<                         # minus 1...
ð  ×                        # spaces...
«                      # with...
®                       # register_c...
«               # with...
¹                    # input...
-                  # minus...
N                   # variable...
Í                 # minus 2...
ð    ×                # spaces...
.ø            # with...
®              # register_c
}           # exit loop
.ø    # surround...
¹         # input...
Í        # minus 2...
ð  ×       # spaces...
.ø    # with...
®      # register_c
}   # exit if statement
»  # join stack by newlines
# implicit output


## GCD

¿
`

Try it online! Built-in function.