Programming Languages Through The Years

161

68

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>

Calvin's Hobbies

Posted 2015-04-06T05:54:55.230

Reputation: 48 376

2This should help. – swish – 2015-04-06T09:10:59.613

19

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

1Being 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

4If 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

@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

@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

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

Answers

165

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

swish

Posted 2015-04-06T05:54:55.230

Reputation: 6 838

107Wow, such +1. Very answer. Much quality. – Alex A. – 2015-04-06T20:08:59.897

27I joined codegolf just to upvote this answer! – Derek Tomes – 2015-04-08T02:36:16.560

21I can't even read the GCD one with a straight face – Cole Johnson – 2015-04-09T07:18:55.710

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

Martin Ender

Posted 2015-04-06T05:54:55.230

Reputation: 162 549

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̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ – 2015-04-06T10:10:56.120

8+1 I was pretty sure 2015 submission would be a language for CodeGolf use. – Sampriti Panda – 2015-04-06T10:31:42.037

@n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ 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

58

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"

enter image description here

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

enter image description here

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

enter image description here

This function definition will then produce this block:

enter image description here

Scimonster

Posted 2015-04-06T05:54:55.230

Reputation: 2 795

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

53

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.

Alex A.

Posted 2015-04-06T05:54:55.230

Reputation: 22 170

13Finally, a language everyone can understand. – ASCIIThenANSI – 2015-04-12T20:05:31.807

23IM 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

40

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:

enter image description here

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

Sp3000

Posted 2015-04-06T05:54:55.230

Reputation: 54 224

25And that was how I found out that the name &gt;&lt;&gt; is a palindrome. – Zev Eisenberg – 2015-04-09T11:54:04.620

40

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:

enter image description here

alexwlchan

Posted 2015-04-06T05:54:55.230

Reputation: 637

17+1 for Real Output! – Sampriti Panda – 2015-04-17T09:38:27.210

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

34

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

PhiNotPi

Posted 2015-04-06T05:54:55.230

Reputation: 18 585

6+1 for using your own language – rpax – 2015-04-07T22:27:06.280

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.

Alex A.

Posted 2015-04-06T05:54:55.230

Reputation: 22 170

26

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.

Mathematica 1.0

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.

Mathematica 2.0

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.

alephalpha

Posted 2015-04-06T05:54:55.230

Reputation: 18 628

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

25

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.

LegionMammal978

Posted 2015-04-06T05:54:55.230

Reputation: 14 318

And they say INTERCAL is weird! – refi64 – 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

23

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 $ a`mod`b

ceased to turn counterclockwis

Posted 2015-04-06T05:54:55.230

Reputation: 5 000

22

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

Optimizer

Posted 2015-04-06T05:54:55.230

Reputation: 23 401

22

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.

Martin Ender

Posted 2015-04-06T05:54:55.230

Reputation: 162 549

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

22

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

marinus

Posted 2015-04-06T05:54:55.230

Reputation: 29 024

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

2+1 for "Flower-power-era". – refi64 – 2015-08-30T19:18:18.940

21

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

swish

Posted 2015-04-06T05:54:55.230

Reputation: 6 838

I'm sorry, I filled in Ruby :) – Sampriti Panda – 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

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!

refi64

Posted 2015-04-06T05:54:55.230

Reputation: 7 567

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! – refi64 – 2015-04-28T21:35:29.183

4PLEASE 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

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

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 $ a`mod`b

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

ceased to turn counterclockwis

Posted 2015-04-06T05:54:55.230

Reputation: 5 000

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

20

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 1

enter image description here

Task 2

enter image description here

Task 3

enter image description here

Scimonster

Posted 2015-04-06T05:54:55.230

Reputation: 2 795

20

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])));
}

marinus

Posted 2015-04-06T05:54:55.230

Reputation: 29 024

Wow, I never realized how much C has changed... Where did you get that compiler from? – refi64 – 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 &gt; 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

1http://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

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

Sp3000

Posted 2015-04-06T05:54:55.230

Reputation: 54 224

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

16

2010 - WTFZOMFG

WTFZOMFG is an esoteric languages based on Brainfuck. It was made by Jay Songdahl in 2010. "WTFZOMFG" is short for "What's That Function? Zen Optimized Malicious File Gophers!" .

Here is a compiler for *nix systems.

Task 1

'WTFZOMFG was made in 2010!\n"

Task 2

/&(-.N%3 >&>s-{-(-. ).N}>{-(-. ).N}_0 '\n")

Explanation:

Sorry. I'm not good at writing explanations.

/                                           # read the number and store it in cell 0
 &                                          # copy it to cell 1
  (                                         # loop while cell 0 isn't 0
   -                                        # decrease the value of cell 0
    .N                                      # print "N"
      %3                                    # copy cell 0 to cell 3
                                            # a space must be added after the number. I don't know if it's a bug of the compiler or a feature.
         >                                  # move to cell 1
          &                                 # copy cell 1 to cell 2
           >                                # move cell 2
            s                               # let cell 2 = cell 2 - cell 3
             -                              # decrease the value of cell 2
              {                             # if cell 2 isn't 0
               -                            # decrease the value of cell 2
                (-. )                       # while cell 2 isn't 0, decrease it and print " "
                     .N                     # print "N"
                       }                    # end if
                        >                   # move cell 3
                         {                  # if cell 3 isn't 0
                          -                 # decrease the value of cell 3
                           (-. )            # while cell 3 isn't 0, decrease it and print " "
                                .N          # print "N"
                                  }         # end if
                                   _0       # move to cell 0
                                      '\n"  # print a newline
                                          ) # 

Task 3

/>>/(<<&>dm<s&>>%0 <&>)<<\

Euclidean algorithm. WTFZOMFG doesn't have a command for mod, so I have to use d (divide), m (multiply) and s (subtract).

alephalpha

Posted 2015-04-06T05:54:55.230

Reputation: 18 628

1+1 for doing task three with no modulus. – Todd Wilcox – 2015-04-10T14:32:02.680

15

2012 - TypeScript

TypeScript is a free and open source programming language developed and maintained by Microsoft.

Main goal is: Any browser. Any host. Any OS. Open Source. It was released on October, 2012

Hello TypeScript

Task1(name:string,year:number) {
    return name + " was made in "+ year +"!";
}

ASCII Art

Task2(n:number,separator:string,space:string) {
    var result:string = "";
    for (var k = 0; k < n; k++)
    {
        for (var j = 0; j < n; j++)
        {
            var i = ((n * k) + j) % n;
            result+=(i == 0 || i == n - 1 || i == k) ? "N" : space;
        }
        result+=separator;
    }
    return result;
}

GCD

Task3(a:number,b:number) {
    while (a != 0 && b != 0)
        {
            if (a > b)
                a %= b;
            else
                b %= a;
        }

        if (a == 0)
            return b;
        else
            return a;
}

try it online, and screencast of it.

vrluckyin

Posted 2015-04-06T05:54:55.230

Reputation: 261

4You forgot to mention one thing: TypeScript is a superset of Javascript with few syntax changes and allows(?) strong-typed variables and arguments. – Ismael Miguel – 2015-04-09T18:27:13.650

1O my god, something open source by MS! – Mega Man – 2016-07-30T10:24:15.647

15

2011 - Dart

Dart is an Open Source programming language developed by Google which is developed as a replacement for Javascript (althought it compiles to javascript). It was unveiled by Google in 2011 during the GOTO conference.

"Hello World!" Variant:

main() {
  print('Dart was made in 2011!');
}

ASCII Art N:

Bruteforce method, runs at 0(n²), but it shouldn't really matter unless you use a giant number.

asciiN(int number){
    if(number == 1){
        print('N');
    }else{
        for(var i = 1; i <= number; i++){
            String currentLine = "";
            for(var j = 1; j <= number; j++){
                if(j==1 || j == number || j == i){
                    currentLine = currentLine + "N";
                }else{
                    currentLine = currentLine + " ";
                }
            }
            print(currentLine);
        }
    }
}

GCD

simple Euclid method ported from the Snap! example above.

int gcd(int first, int second){
if(second > first){
   return gcd(second, first);
    }else{
        if(first == 0){
            return second;
        }else{
            if(second ==0){
                return first;
            }else{
                return gcd(second, first-second);
            }
        }
    }
}

Nzall

Posted 2015-04-06T05:54:55.230

Reputation: 336

4I don't think that you can output a n × n ASCII art in less than O(n²). – Paŭlo Ebermann – 2015-04-06T19:22:13.597

@PaŭloEbermann I'm not that familiar with big O notation or how to calculate complexity, but the Julia example looks like it's not O(n²). – Nzall – 2015-04-06T19:28:36.710

@AlexA. The println() function prints a string of n characters. I think that function call needs at least time O(n) to execute. In the loop, so O(n²) for the whole program. – Paŭlo Ebermann – 2015-04-06T20:07:52.030

@AlexA. I think what Ebermann is talking about is that you have N string concatenation operations in your print function. we both do n² string concatenations in our functions. I do them once per inner loop iteration, you do them for every println(). – Nzall – 2015-04-06T20:18:55.563

@NateKerkhofs: Ahhhhh okay. I was completely missing the point. Thanks. I guess the Julia answer is O(n^2). – Alex A. – 2015-04-06T20:21:18.463

+1 for reusing my code. :) – Scimonster – 2015-04-07T06:53:56.403

1If this was not ascii art it would be O(n) to display an N. (draw 3 lines to the screen, each line is O(n) therefore O(n) complexity). Or, you could say, rendering the N has O(N) complexity... hehe – Rodolvertice – 2015-04-07T21:01:20.687

15

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

wasikuss

Posted 2015-04-06T05:54:55.230

Reputation: 351

Could you add a snippet showing how to input two space-seperated integers from the stdin? – Sampriti Panda – 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

15

2009 - Go

Go is programming language developed by Google. The development started in 2007, but Go was announced in November 2009.

Go is a statically-typed language influenced by C which emphasizes conciseness, simplicity, and safety.

Task 1:

package main
import "fmt"

func main(){
    fmt.Println("Go was made in 2009!")
}

The first line declares the package of the code. Even a simple example as printing one line needs to be part of one package. And the executable is always called main.

Task 2:

package main

import (
        "fmt"
        "strings"
)

func main(){
    var n int
    fmt.Scan(&n)

    for i := 0; i < n; i++ {
        a := make([]string, n, n)
        for j := 0; j < n; j++ { a[j] = " " }

        a[0] = "N"
        a[i] = "N"
        a[n-1] = "N"

        s := strings.Join(a, "")
        fmt.Println(s)
    }
}

Go has a quite concise variable declaration (i := 0 is the same as var i int = 0), and the compiler determines the type. This is usually a feature more common in dynamic languages. Using this short notation it's also really easy to assign functions to variables (f := func(x int) int {/* Code */}) and create Closures.

Task 3:

package main

import "fmt"

func gcd(a, b int) int {
    for b != 0 {
        a, b = b, a%b
    }
    return a
}

func main(){
    var a, b int
    fmt.Scan(&a)
    fmt.Scan(&b)

    fmt.Println(gcd(a, b))
}

Here you can see the a, b = b, a%b syntax, which is really nice. I don't know the exact name, but in Python it's called tuple unpacking. Using the same way you can return multiple values from a function (func f() (int, string) { return 42, "Hallo"}).

Another thing happening in this code is the loop. The for loop is the only loop in Go. While-loops or do-while-loops don't exists. But you can easily create an equivalent for the while loop for condition {} or an infinite loop for {}.

Jakube

Posted 2015-04-06T05:54:55.230

Reputation: 20 252

15

2015 - MuffinMC

MuffinMC is a Turing-complete, funny (but serious), functional and minimalist macro-language written by Franck Porcher (http://franckys.com) in mid-February 2015 out of necessity as a (quick) tool to empower a spreadsheet to be used as the only front-end controller to pilot and drive all inventory-related operations associated with a Prestashop-based merchant site for a new Tahitian fashion brand : Mutiny Tahiti (http://mutinytahiti.com -- soon to be launched).

MuffinMC is an acronym for MUtiny Functional Flexible INline Macro Command language.

To meet our requirements, MuffinMC's core features have been designed around flexible and efficient 1st-class built-in semantic constructs like iterators, lazy-evaluation, multi-functors, string-product.

MuffinMC draws its roots in (pragmatic) functional programming, FLisp and Perl. It fully supports recursivity (without any optimization), is dynamically typed and dynamically scoped (shallow-binding). It offers its users one data structure only, apart from basic data-types atoms (atoms, strings, numerals) : lists !

MuffinMC list semantics (kind of) borrows on power-set semantics, that is :

  1. All MuffinMC operation yield a list, possibly empty.
  2. Access to an any individual list element always yields a one-value-list made of that element (think of it as a singleton).
  3. The empty list is the neutral element on list operations.

To reconcile with this, the following may help :

  • One may visualize a list as the element of the list's power-set that has the greatest cardinality.
  • Visualize a list's element as the element of the list's power-set that is the singleton made of that element.
  • Visualize an empty list as the empty-set; that is, the only element of the empty-set's power-set.

As such, accessing an empty list element yields the empty-list, and not an error! Indeed, MuffinMC tries hard to throw as few errors as possible by extending that way the semantics of many traditional operations.

Task 1

#(say "MuffinMC was born in 2015 out of necessity !")

#(...) is the MuffinMC macro command for applying a function on a non-evaled argument list, here the built-in function say, borrowed from Perl.

#(say 1 2 3 ...) is functionally identical to map {say $_} (1,2,3,...)

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.

Franck Porcher

Posted 2015-04-06T05:54:55.230

Reputation: 171

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 – Rodolvertice – 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

1991 - Python

Language History

In the late 1980s, Guido van Rossum began devising Python as a hobby. Its name comes from Monty Python's Flying Circus, a British television show of which Rossum is a fan. The first Python implementation began in 1989 and was released in 1991. It has surged in popularity over the years, becoming the language of choice for many introductory computer science courses.

"Hello, World!" Variant

print("Python was made in 1991!")

Note the parentheses around the input to print. Though this syntax works in Python 2, typically in Python 2 you would omit these parentheses. However, they're required in Python 3. As suggested by Zach Gates, parentheses are used throughout to ensure that the code presented here will work across versions.

ASCII Art N

def asciin(n):
    if n == 1:
        print("N")
    else:
        print("N" + " "*(n-2) + "N")

        for i in range(2, n):
            print("N" + " "*(i-2) + "N" + " "*(n-i-1) + "N")

        print("N" + " "*(n-2) + "N")

Functions are defined using def. String concatenation is performed using + and string repetition with *.

GCD

def gcd(a, b):
    if b == 0:
        return(a)
    else:
        return(gcd(b, a % b))

Note that Python requires structured whitespace.

Alex A.

Posted 2015-04-06T05:54:55.230

Reputation: 22 170

15

1968 - Algol 68

Algol 68 was defined by the IFIP Working Group 2.1 as a successor to Algol 60.

It is an expression oriented language in which everything has a value. It is also orthogonal, in which you can use any construct in any way. This means that expressions can be on the RHS and the LHS of an assignment, for example.

All control structures have an abbreviated form as well as a long form using expressions. It also permits the definitions of operators.

The goals of the language are cited as:

The main aims and principles of design of ALGOL 68:

  • Completeness and clarity of description
  • Orthogonal design,
  • Security,
  • Efficiency
  • Static mode checking
  • Mode-independent parsing
  • Independent compilation
  • Loop optimization
  • Representations - in minimal & larger character sets

These programs have been tested with the Algol 68 Genie interpreter, which is a complete implementation of the language.

Some features that modern programmers may find different, is that empty statements are not permitted. You cannot just add ; everywhere. You have to use the SKIP statement if you want to explicitly have nothing. It also permitted the coding of concurrent programs very easily. Algol 68 also, notably, used backwards keywords as terminators, such as esac, od, fi etc.

The language had a representation used for writing the code that used many fonts representing keywords in bold, and identifiers in italic, for example. At the time, and probably still, no compiler implemented this feature of the design. The language permitted several different concrete representations of programs using stropping modes. This allowed programs to be prepared using limited character sets, such as might be found in computers in the 1960s. Consider the a short program fragment, which would be represented as:

if i < 0 then skip fi

This could be prepared for a compiler in prime stropping mode as:

'IF' I 'LT' 0 'THEN' 'SKIP' 'FI'

In dot stropping mode this would be:

.IF I .LT 0 .THEN .SKIP .FI

In case stropping mode this would be:

IF i < 0 THEN SKIP FI

I have great fondness for this language as I worked on one of the compiler implementations, as well as programming in it exclusively for many years.

Task 1

print (("Algol 68 was made in 1968!", newline))

The point to note here is the double parentheses. This is because print is a function that takes a single argument which is a variable length array of the union of all types. The inner parenthesis are the array constructor. This is how polymorphism is handled in this strongly typed language.

In case stropping mode:

print (("Algol 68 was made in 1968!", newline))


C:\>a68g HelloWorld.a68
Algol 68 was made in 1968!

Task 2

     int n;
     read ((n));
     for i from 1 to n do
          for j from 1 to n do
               ¢ here we use an abbreviated IF clause ¢
               print (( ( j = 1 OR j = i OR j = n |
                    "N"
               |
                    " "
               ) ))
          od ;
     print ((newline))
     od

In case stropping mode:

 INT n;
 read ((n));
 FOR i FROM 1 TO n DO
        FOR j FROM 1 TO n DO
            CO here we use an abbreviated IF clause CO
            print (( ( j = 1 OR j = i OR j = n |
                 "N"
            |
                 " "
            ) ))
        OD ;
        print ((newline))
    OD

C:\>a68g ASCIIart.a68
8
N      N
NN     N
N N    N
N  N   N
N   N  N
N    N N
N     NN
N      N

Task 3

     ¢ we can define our own operators in Algol 68 ¢
     op % = ( int a, b) int:
          ((b = 0 |
               a
          |
               b % (a mod b)
          ));
     int i,j;
     read((i,j));
     print(( i % j , newline))

In case stropping mode:

COMMENT we can define our own operators in Algol 68 COMMENT
OP % = ( INT a, b) INT:
    ((b = 0 |
        a
    |
       b % (a MOD b)
    ));
INT i,j;
read((i,j));
print(( i % j , newline))


C:\>a68g GCD.a68
4 12
         +4

Brian Tompsett - 汤莱恩

Posted 2015-04-06T05:54:55.230

Reputation: 359

7These were probably the first Algol 68 programs I have written and executed in over 30 years. I found it so moving, that it actually brought me to tears. I never realised a "Hello World!" program could be so emotional! – Brian Tompsett - 汤莱恩 – 2015-05-09T17:01:55.343

1I was so looking forward to the Languages of the '60s and was ready with BCPL, Simula, CORAL66, Fortran 66, PL/1, SNOBOL4, POP-1 and a whole raft more, only to discover that the rules are that I have to wait 5 years of languages... A least there is a rich furrow for someone else to plough. – Brian Tompsett - 汤莱恩 – 2015-05-09T22:43:22.917

It's really cool to see the differences between Fortran66 (utter mess of punchcard violence), APL (weird clutter of superpower-symbols), and Algol68, which is actually pretty beautiful. Today, you'd need to look into esoteric languages to find such a variety of different approaches... back then, this was rather mainstream, wasn't it? – ceased to turn counterclockwis – 2015-05-19T16:47:12.963

Of course, the Revised Report wasn't published until eh, 1976 was it? At least that is the copyright year that Springer gives. And the scan I found mentions 1978. – Rhialto – 2017-07-05T19:59:20.893

[1] A. van Wijngaarden (ed.), B.l. Mailloux, 1.E.L. Peck, C.B.A. Koster, Report on the algorithmic language ALGOL 68, Numer. Math. 14 (1969) 79-218; also in Kibenietika 6 (1969) and 7 (1970) . [2] A. van Wijngaarden, B.l. Mailloux, 1.E.L. Peck, C.B.A. Koster, M: Sintzoff, C.B.Lindsey, L.G.L. T. Meertens and R.G. Fisker, Revised report on the algorithmic language ALGOL 68, Acta Informat. 5 (1975) parts 1-3 (reprints published by Springer, Berlin, and also as Mathematical Centre Tract 50 by the Mathematisch Centrum, Amsterdam); also in SIGPLAN Notices 12 (5) (1977) – Brian Tompsett - 汤莱恩 – 2017-07-05T21:11:00.163

15

1964 - Dartmouth BASIC

BASIC is a family of general-purpose, high-level programming languages whose design philosophy emphasizes ease of use. In 1964, John G. Kemeny and Thomas E. Kurtz designed the original BASIC language at Dartmouth College in New Hampshire. They wanted to enable students in fields other than science and mathematics to use computers.

I'm looking at this manual on BASIC from 1964, and this emulator of the Darthmouth Time Sharing System it ran on. The server is still up, but sadly, registering an account seems to be impossible. For now, these programs should theoretically work:

Task 1

10 PRINT "BASIC WAS MADE IN 1964"
20 END

Task 2

10 READ N
15 FOR Y = 1 TO N STEP 1
20 FOR X = 1 TO N STEP 1
25 IF X = 1 THEN 50
30 IF X = N THEN 50
35 IF X = Y THEN 50
40 PRINT " ",
45 GO TO 55
50 PRINT "N",
55 NEXT X
60 PRINT
65 NEXT Y
70 DATA 5
75 END

Outputting something like:

N                       N
N     N                 N
N           N           N
N                 N     N
N                       N

Note how the input is typed in as part of the program (70 DATA 5); the READ instruction way at the top fetches data from there. There is no string concatenation, but section 3.1 of the manual describes how PRINT results are written to tabulated "zones" on the output.

Task 3

The slow version of Euclid's algorithm:

10 READ A, B
20 IF A = B THEN 80
30 IF A < B THEN 60
40 LET A = A - B
50 GO TO 20
60 LET B = B - A
70 GO TO 20
80 PRINT A
85 DATA 144, 250
90 END

Outputting:

2

Lynn

Posted 2015-04-06T05:54:55.230

Reputation: 41 980

Finally, someone did BASIC. – marinus – 2015-08-28T15:02:16.277

15

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 =
DEC.DGT '' DEC.IN                  /S($DEC.FIN)
        .X = DEC.IN
        DEC.IN =
DEC.DIV .X '##########' =          /F(DEC.ADD)
        DEC.IN = DEC.IN '#'        /(DEC.DIV)
DEC.ADD '' .X                      /S(DEC.0)
        '#' .X                     /S(DEC.1)
        '##' .X                    /S(DEC.2)
        '###' .X                   /S(DEC.3)
        '####' .X                  /S(DEC.4)
        '#####' .X                 /S(DEC.5)
        '######' .X                /S(DEC.6)
        '#######' .X               /S(DEC.7)
        '########' .X              /S(DEC.8)
        '#########' .X             /S(DEC.9)
DEC.0   DEC.R = '0' DEC.R          /(DEC.DGT)
DEC.1   DEC.R = '1' DEC.R          /(DEC.DGT)
DEC.2   DEC.R = '2' DEC.R          /(DEC.DGT)
DEC.3   DEC.R = '3' DEC.R          /(DEC.DGT)
DEC.4   DEC.R = '4' DEC.R          /(DEC.DGT)
DEC.5   DEC.R = '5' DEC.R          /(DEC.DGT)
DEC.6   DEC.R = '6' DEC.R          /(DEC.DGT)
DEC.7   DEC.R = '7' DEC.R          /(DEC.DGT)
DEC.8   DEC.R = '8' DEC.R          /(DEC.DGT)
DEC.9   DEC.R = '9' DEC.R          /(DEC.DGT)

FIN     START

marinus

Posted 2015-04-06T05:54:55.230

Reputation: 29 024

Excellent background work! Not much for 1961 - it looks like COMIT is all we have.... – Brian Tompsett - 汤莱恩 – 2016-01-21T09:26:37.813

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

GoatInTheMachine

Posted 2015-04-06T05:54:55.230

Reputation: 463

14

2007 - Clojure

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

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

Task 1

(println "Clojure was made in 2007!")

Task 2

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

(ascii (read))

Task 3

(defn gcd [a b]
    (if (zero? b) a (recur b (mod a b)))
)
(println (gcd (read) (read)))

Sampriti Panda

Posted 2015-04-06T05:54:55.230

Reputation: 620

1Iirc, (or) can accept any number of arguments. (inc j) and (inc i) both do nothing (their return values aren't captured). I would also recommend to return the string instead of just printing it (Clojure isn't exactly meant to be procedural). Hint: (for) – seequ – 2015-04-10T18:26:59.993

@Sieg Thanks! I'm new to Clojure and am still learning. – Sampriti Panda – 2015-04-11T06:04:46.043

1

You're not supposed to close off parentheses on separate lines in a Lisp. For instance clojuredoc refers to the Scheme style guide when it comes to formatting and indentation, and the Scheme guide calls it unacceptable: Absolutely do *not* place closing brackets on their own lines.

– daniero – 2015-05-03T17:16:43.293

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)

kuldeep.kamboj

Posted 2015-04-06T05:54:55.230

Reputation: 595

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

xfix

Posted 2015-04-06T05:54:55.230

Reputation: 9 392

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

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.

Lynn

Posted 2015-04-06T05:54:55.230

Reputation: 41 980

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.

– xfix – 2015-11-14T15:15:52.213

13

1966 - Fortran 66

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

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

Task 1

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

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

Task 2

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

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

Task 3

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

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

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

An 80 Column Punched Card

kuldeep.kamboj

Posted 2015-04-06T05:54:55.230

Reputation: 595

13

1965 - Atlas Autocode

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

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

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

Task 1

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

Task 2

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

Task 3

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

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

Manchester MUSS Alumni

Posted 2015-04-06T05:54:55.230

Reputation: 301

The underlining is hard to get right on all browsers. If it does not display properly - try another browser. If you know how to do it better let me know! – Manchester MUSS Alumni – 2015-05-24T21:14:23.507

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

Alex A.

Posted 2015-04-06T05:54:55.230

Reputation: 22 170

2

According to Wikipedia, C# first appeared in 2000.

– Sampriti Panda – 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

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.

alephalpha

Posted 2015-04-06T05:54:55.230

Reputation: 18 628

Should it not be if (zero? n) in the gcd? – VisualMelon – 2015-04-15T07:34:45.193

@VisualMelon Thanks. – alephalpha – 2015-04-15T08:00:51.317

1

Isn't Racket just one of the 30+ implementations of Scheme_implementations)? 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). – Harald Korneliussen – 2016-11-29T13:12:40.967

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%

Mark

Posted 2015-04-06T05:54:55.230

Reputation: 1 896

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 – 2017-07-05T19:37:49.970

12

1985 - Dr. LOGO

Dr. LOGO splash-screen

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

The procedures:

Screen shot of LOGO procedures

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

Task 1

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

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

Task 1 output

Task 2

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

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

Task 2 output

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

Task 2 bonus output

Task 3

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

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

Task 3 output

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

CJ Dennis

Posted 2015-04-06T05:54:55.230

Reputation: 2 559

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

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

Sampriti Panda

Posted 2015-04-06T05:54:55.230

Reputation: 620

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

Sampriti Panda

Posted 2015-04-06T05:54:55.230

Reputation: 620

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.

alephalpha

Posted 2015-04-06T05:54:55.230

Reputation: 18 628

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

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.

Scimonster

Posted 2015-04-06T05:54:55.230

Reputation: 2 795

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

11

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.

Amos M. Carpenter

Posted 2015-04-06T05:54:55.230

Reputation: 431

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

10

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)

swish

Posted 2015-04-06T05:54:55.230

Reputation: 6 838

10

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

plannapus

Posted 2015-04-06T05:54:55.230

Reputation: 8 020

2Nice, +1! I especially like the matrix solution for the ASCII N. To make things a little prettier you could also add &lt;!-- language-all: lang-r --&gt; 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

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.

MickyT

Posted 2015-04-06T05:54:55.230

Reputation: 9 062

10

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;

marinus

Posted 2015-04-06T05:54:55.230

Reputation: 29 024

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

10

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

MickyT

Posted 2015-04-06T05:54:55.230

Reputation: 9 062

@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

10

1968 - Refal

Finally, a programming language from the Soviet Union.

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

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

Task 1

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

Task 2

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

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

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

Task 3

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

GCD { s.1 0   = s.1;
      s.1 s.2 = <GCD s.2 <Mod s.1 s.2>>; }

alephalpha

Posted 2015-04-06T05:54:55.230

Reputation: 18 628

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

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
     §

Brian Tompsett - 汤莱恩

Posted 2015-04-06T05:54:55.230

Reputation: 359

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

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
    {
        gcd $b ($a % $b)
    }
}

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

VisualMelon

Posted 2015-04-06T05:54:55.230

Reputation: 3 425

9

2002 - Io

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

Task 1:

"Io was made in 2002!" println

Task 2:

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

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

Task 3:

task3 := method(g,q, (q==0) ifTrue(writeln(g)) ifFalse(task3(q, g%q)))

Def

Posted 2015-04-06T05:54:55.230

Reputation: 557

9

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)

Sampriti Panda

Posted 2015-04-06T05:54:55.230

Reputation: 620

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

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

9

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]

refi64

Posted 2015-04-06T05:54:55.230

Reputation: 7 567

9

1993 - Batch

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

Hello World.bat

@echo off
echo Batch was created in 1993!
pause

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

ASCII N.bat

@echo off
setLocal enableDelayedExpansion

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

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

GCD.bat

@echo off
setLocal enableDelayedExpansion

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

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

echo !h!

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

Hacker Aesthetic

unclemeat

Posted 2015-04-06T05:54:55.230

Reputation: 1 806

3Some people's batch skills amaze me. – refi64 – 2015-04-16T01:53:26.480

@kirbyfan64sos Nice of you to say :) – unclemeat – 2015-04-16T03:28:48.790

9

1995 - Java

History

Java is a general-purpose language that runs on a large variety of systems, from web servers to smart phones and disc players. Development started in 1991 at Sun Microsystems, version 1.0 was released in 95. In 99, version 1.2 was renamed to "Java 2". Java is very verbose and thus unsuitable for code golfing, which hasn't stopped some from trying. It also has a reputation for yielding over-engineered solutions and being generally clumsy. Basically, just like this text.

Hello World

class M{public static void main(String[]a){System.out.print("Java was made in 1995");}}

(golfed as much as possible)

ASCII N

public class Main {
    public static void main (String[] args) {
        int n = Integer.parseInt(args[0]);
        for (int i = 0; i < n; i++) {
            System.out.print('N');
            for (int j = 1; j < n-1; j++) {
                System.out.print(j == i ? 'N' : ' ');
            }
            System.out.println('N');
        }
    }
}

GCD

public class Main {
    public static void main (String[] args) {
        int a = Integer.parseInt(args[0]);
        int b = Integer.parseInt(args[1]);
        System.out.printf("GCD of %d and %d: %d%n", a, b, gcd(a, b));
    }

    public static int gcd(int a, int b) {
        if (b > a) return gcd(b, a);
        else if (b == 0) return a;
        else if (a == 0) return b;
        else return gcd(b, a%b);
    }
}

Cephalopod

Posted 2015-04-06T05:54:55.230

Reputation: 545

2+1 for applying Java coding style to the history paragraph ;) – DLosc – 2015-04-15T19:23:57.800

I would still use % instead of - in the last gcd call. – Paŭlo Ebermann – 2015-04-17T20:59:28.190

"golfed as much as possible", lol. no. Remove the space after String[], and change println to print. – mbomb007 – 2015-04-21T15:45:31.413

fixed, also renamed args to a – Cephalopod – 2015-04-22T18:49:42.957

9

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

refi64

Posted 2015-04-06T05:54:55.230

Reputation: 7 567

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... ;) – refi64 – 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. – refi64 – 2015-04-17T20:49:03.807

9

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

marinus

Posted 2015-04-06T05:54:55.230

Reputation: 29 024

9

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.

Leushenko

Posted 2015-04-06T05:54:55.230

Reputation: 1 470

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

8

1997 - Fortran 95

I am a bit late with this answer, since Fortran 95 wasn't published until 1997. Oh well. From Wikipedia:

Fortran 95, published officially as ISO/IEC 1539-1:1997, was a minor revision, mostly to resolve some outstanding issues from the Fortran 90 standard. Nevertheless, Fortran 95 also added a number of extensions, notably from the High Performance Fortran specification.

“Hello, World!”

program say_my_name
  print '(A)', "The Fortran 95 standard was published in ... 1997."
end program say_my_name

ASCII art “N”

For the ASCII art task, Fortran's formatted i/o is actually quite handy:

program paint_N
  integer            :: N, i
  character(len=500) :: fmt

  read*, N

  do i=1,N
     write(fmt, "('(', 2(A, ',', 'T', I0, ','), A, ')')") &
          "'N'", i, "'N'", N, "'N'"
     print fmt
  end do
end program paint_N

Greatest common divisor

For the GCD task I chose the binary method. The bitwise intrinsics (IAND, IOR, ISHFT), as well as user-defined pure functions, were only introduced with Fortran 95. Also, I took the liberty of adding a loop so you can compute more than one GCD per execution. The algorithm is a straightforward translation of http://en.wikipedia.org/wiki/Binary_GCD_algorithm#Iterative_version_in_C.

program binary_GCD_algorithm
  integer :: a, b

  do
     read(*,*, END=1) a, b
     print*, gcd(a,b)
  end do

1 continue

contains

  pure integer function gcd(a, b)
    integer, intent(in) :: a, b
    integer             :: shift, u, v, t

    u = a
    v = b

    if (u == 0) then
       gcd = v
    else if (v == 0) then
       gcd = u
    else
       shift = 0
       find_shift: do while (iand(ior(u, v), 1) == 0)
          u = ishft(u, -1)
          v = ishft(v, -1)

          shift = shift+1
       end do find_shift

       halve_u: do while (iand(u, 1) == 0)

          u = ishft(u, -1)
       end do halve_u

       reduce_v: do
          halve_v: do while (iand(v, 1) == 0)

             v = ishft(v, -1)
          end do halve_v

          swap: if (u > v) then
             t = v
             v = u
             u = t
          end if swap

          v = v - u

          if (v == 0) exit reduce_v
       end do reduce_v

       gcd = ishft(u, shift)
    end if
  end function gcd
end program binary_GCD_algorithm

xebtl

Posted 2015-04-06T05:54:55.230

Reputation: 886

Just in case you missed the note, posting versions of programming languages is discouraged unless the version is significantly different than its predecessors. I see that your code in your Fortran 90 answer does offer different task solutions, which is good, but I'm no Fortran expert and can't say how much it's really worth having both versions. I'd say to refrain from posting any more Fortran versions until the original Fortran.

– Calvin's Hobbies – 2015-04-16T23:40:43.483

@Calvin'sHobbies Not to worry, I won't be tackling any older versions, and I don't know what the 2003/2008 versions would have to add. It is sometimes difficult to say what is a “different language”, and I would argue that at least Fortran pre-90 (fixed format) and post-90 are “different”, but not really 90 and 95, I admit. If you prefer, I can delete one of the answers. Neither of them are needed for the chain. – xebtl – 2015-04-17T11:42:54.530

To be honest, after seeing a “C++98” answer, I thought Fortran 95 should qualify as well, and the year was about right. Then I realized that 90/95 could actually make difference for the GCD task. – xebtl – 2015-04-17T11:43:30.093

8

1995 - PHP

PHP began life as a project of Rasmus Lerdorf, intended to help him manage his personal homepage. The original name was Personal Home Page Tools, later changed to Personal Home Page/Forms Interpreter (PHP/FI). Lerdorf never intended to create a programming language, but things snowballed, a development team was formed, and the rest is history. PHP is now used extensively for server-side scripting as one of the options for the P in LAMP (or WAMP); more-recent versions have added support for command-line and client-side GUI applications as well.

Syntax is closest to Perl, with $ used for variables and implicit casting between strings and numbers. Like JavaScript, PHP has been criticized for its ad-hoc construction, which resulted in numerous weird quirks and inconsistencies; nevertheless, I find it fairly easy to work with in practice. The PHP language reference is always helpful.

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:

PHP three tasks

DLosc

Posted 2015-04-06T05:54:55.230

Reputation: 17 064

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 :) – Harald Korneliussen – 2016-11-29T12:55:08.500

8

1984 - Standard ML

Standard ML is a descendant of the ML programming language. It's a functional programming language with strong, compile-time type checking and inference.

I work with Haskell a lot, and comparing it to that, Standard ML seems less pure, and definitely lacks a lot of the nice syntactic sugar that Haskell has. Nonetheless, the type system looks neat, and code written in it looks elegant.

(I, too, learned this language just to answer the challenge, and because I've been interested in older functional languages like ML and Miranda. If you're a Standard ML expert, and notice something in this code looks really unidiomatic, feel free to point it out.)

Task 1

print "Standard ML was made in 1984!\n";

The print function prints the given string to standard output. Not much to say here.

Task 2

fun asciiArt (s : int) : string =
  let
    fun line n = implode (List.tabulate (s,
      fn i => if i = 0 orelse i = n orelse i = s - 1
                then #"N"
                else #" "
    ))
  in
    String.concatWith "\n" (List.tabulate (s, line))
  end;

fun readInt h =
  Option.valOf (TextIO.scanStream (Int.scan StringCvt.DEC) h);

print "Size: ";
val s = readInt TextIO.stdIn;

print (asciiArt s);

To get some asciiArt of size s, we define a helper function that gets us the nth line, then generate a bunch of lines and concatenate them with newlines. We read a number from TextIO.stdIn and print the corresponding ASCII art N.

The List.tabulate function is basically: tabulate (n, f) = [f 0, f 1, ... f (n-1)].

Task 3

fun gcd (a : int) (b : int) : int =
  if b = 0 then a else gcd b (a mod b);

fun readInt h =
  Option.valOf (TextIO.scanStream (Int.scan StringCvt.DEC) h);

print "First number: ";
val a = readInt TextIO.stdIn;
print "Second number: ";
val b = readInt TextIO.stdIn;

print ("The GCD of " ^ Int.toString a ^ " and " ^ Int.toString b ^
       " is " ^ Int.toString (gcd a b) ^ ".\n");

We implement the Euclidean GCD algorithm recursively, read two numbers, and print the result. There's no built-in GCD function, it seems. ^ is an interesting choice of string concatenation operator.

Lynn

Posted 2015-04-06T05:54:55.230

Reputation: 41 980

8

1975 - Scheme

Scheme is one of the older and most successful dialects of the LISP family of languages. It predates Common Lisp, Emacs Lisp, and most others still in use.

Its philosophy is based on minimalism and extensibility.

The basic language is made of a minimal set of syntax rules; 12 "fundamental forms," or keywords that need to be specifically implemented by the runtime, such as if and define; and 11 "library forms," keywords that are part of the language definition, but can be internally implemented using the fundamendal forms.

The minimalism is coupled with extreme extensibility. Scheme's macro system is arguably the most advanced hygienic, Turing-complete pre-processor of all programming languages. It is to C's macro preprocessor as a Ferrari is to a soap box!

Scheme's unique philosophy and its hacker-friendly minimal footprint have always attracted many thinkers and tinkerers alike. 40 years after its inception we have dozens of implementations, running on all sorts of platforms and using all manner of compiler or interpreter technologies, including very bizarre but effective ones. Scheme is an excellent testbed for programming language ideas, but it is also a great language for everyday programming.

Its syntax may appear strange to those unfamiliar with LISP, but it has many advantages, starting with its regularity. Every function, operator, and control structure of the language takes the same form: (name arguments...) where both the name and the arguments may be nested expressions. This simplicity and regularity makes Scheme the ideal language for teaching programming to novice students, as demonstrated by the success of Structure and Interpretation of Computer Programs by MIT Press. Citing Wikipedia:

Before SICP, the introductory courses were almost always filled with learning the details of some programming language, while SICP focuses on finding general patterns from specific problems and building software tools that embody each pattern.

Hello World!

(begin
  (display "Scheme was made in 1975!")
  (newline))

ASCII Art N

(let ((n (read)))
  (let row ((r 1))
    (let col ((c 1))
      (display (if (memq c (list 1 n r))
                   "N" " "))
      (if (< c n)
          (col (+ c 1))
          (newline)))
    (if (< r n)
        (row (+ r 1)))))

GCD

(let gcd ((m (read))
          (n (read)))
  (if (zero? n)
      m
      (gcd n (modulo m n))))

Tobia

Posted 2015-04-06T05:54:55.230

Reputation: 5 219

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) 

wasikuss

Posted 2015-04-06T05:54:55.230

Reputation: 351

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

@Runer112, thanks – wasikuss – 2015-04-10T12:58:20.557

@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">[#!!
       !( !}
%.         !
@
>,#!;{"$"(\
.  >;,!
!:,]&/!

The first bit of the program (before the @) just asks for two numbers and stores them in the two available registers. The last bit is Euclid's algorithm:

  • ,#: while , is nonzero:
  • ;,/&]: push ; mod ,
  • ,:: store the value of the , register in the ; register
  • .: store the remainder that was pushed earlier in the , register
  • {;: afterwards, output the contents of the ; register

marinus

Posted 2015-04-06T05:54:55.230

Reputation: 29 024

7

1997 - ECMAScript

ECMAScript is the standard that arose from JavaScript.

JavaScript was announced to the world in December 1995 by Netscape, and supported in Netscape Navigator in March 1996. Microsoft made a similar language, JScript, which was included in Internet Explorer 3.0 in August 1996.

In November 1996, Netscape took the language to Ecma International, a non-profit standards organisation that worked on the specification. This was published as ECMA-262, which was first released in June 1997. The name is apparently a compromise between Netscape and Microsoft, whose arguments were a major part of drafting the first standard.

Eagle-eyed viewers will note that my solution is essentially JavaScript with a different title; JavaScript is supposed to be compliant with ECMAScript, and then add a few features of its own. As such, I was able to write this without having to look up any ECMAScript syntax.

ECMAScript fiddle to try my code.

Task 1

var challenge1 = function() {
  console.log("ECMAScript was made in 1997!");
};

Task 2

var challenge2 = function(N) {
  for (var row=1; row<=N; row++) {

    var row_str = "N";
    for (var col=2; col<N; col++) {
      if (col == row) {
        row_str += "N";
      } else {
        /* We have to use non-breaking spaces because repeated normal spaces 
           are compressed into a single space when printed. */
        row_str += "&nbsp;";
      }
    }
    row_str += "N";

    console.log(row_str);
  }
};

Task 3

var challenge3 = function(a, b) {
  while (b != 0) {
    var t = b;
    b = a % b;
    a = t;
  }
  return a;
}

alexwlchan

Posted 2015-04-06T05:54:55.230

Reputation: 637

7

2003 - Groovy

Groovy is a dynamic programming language made for the Java platform. Its development was started by James Strachan in 2003.

Task 1 - Hello World

println "Grails was made in 2003!"

Test 2 - ASCII "N"

def i=5
def range=(1..i)
println (range.collect { r->
    range.collect{c->
        (r==c||c==range.min()||c==range.max())?'N':' '
    }.join()
}.join("\n"))

Test 3 - GCD

def GCD;
GCD = {a,b->b==0?a:GCD(b,a%b)}
println GCD(a,b)

Danilo

Posted 2015-04-06T05:54:55.230

Reputation: 171

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.

DLosc

Posted 2015-04-06T05:54:55.230

Reputation: 17 064

7

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.

ɐɔıʇǝɥʇuʎs

Posted 2015-04-06T05:54:55.230

Reputation: 4 355

7

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

alephalpha

Posted 2015-04-06T05:54:55.230

Reputation: 18 628

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

Try clu2c.

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

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

1

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

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

7

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.

Lynn

Posted 2015-04-06T05:54:55.230

Reputation: 41 980

7

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 . 

mbomb007

Posted 2015-04-06T05:54:55.230

Reputation: 16 876

3

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

7

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 at present no known MU5 emulators and no running MUSS systems so 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:

Hello in Flocoder

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:

ASCII art in FLOCODER

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:

GCD in FLOCODER

Manchester MUSS Alumni

Posted 2015-04-06T05:54:55.230

Reputation: 301

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.

DLosc

Posted 2015-04-06T05:54:55.230

Reputation: 17 064

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

ActionScript "Hello World" variant

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.

ActionScript ASCII "N"

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 = "";
    }
}

ActionScript GCD

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

DLosc

Posted 2015-04-06T05:54:55.230

Reputation: 17 064

6

1991 - Fortran 90

From Wikipedia:

The much delayed successor to FORTRAN 77, informally known as Fortran 90 (and prior to that, Fortran 8X), was finally released as ISO/IEC standard 1539:1991 in 1991 and an ANSI Standard in 1992. In addition to changing the official spelling from FORTRAN to Fortran, this major revision added many new features to reflect the significant changes in programming practice that had evolved since the 1978 standard

“Hello, World”

In particular, Fortran 90 adds free-form source input (yay!), which is nice even for Hello World.

program say_my_name
  print '(A)', "Fortran 90 was made in (you guessed it) 1991"
end program say_my_name

ASCII art “N”

In the ASCII art task, the handy I0 format specifier from Fortran 95 has to go. Too bad if you want to print N for N ≥ 10¹⁰

program paint_N
  integer            :: N, i
  character(len=500) :: fmt

  read*, N

  do i=1,N
     write(fmt, "('(', 2(A, ',', 'T', I11, ','), A, ')')") &
          "'N'", i, "'N'", N, "'N'"
     print fmt
  end do
end program paint_N

Greatest common divisor

To compute the GCD, we use Euclid's algorithm because Fortran 90 lacks the bitwise operations. (Even if ifort -e90 accepts them; gfortran has -std=f95 but no corresponding std=f90.)

program Euclidean_GCD_algorithm
  integer :: a, b

  do 
     read(*,*, END=1) a, b
     print*, gcd(a,b) 
  end do

1 continue

contains

  integer function gcd(a, b)
    integer, intent(in) :: a, b
    integer             :: v, t

    gcd = a 
    v   = b

    do while (v /= 0)
       t   = v
       v   = mod(gcd, v)
       gcd = t 
    end do
  end function gcd
end program Euclidean_GCD_algorithm

xebtl

Posted 2015-04-06T05:54:55.230

Reputation: 886

1Oh my - we're officially into languages that are older than me. – Commander Coriander Salamander – 2015-04-16T05:56:39.450

Well, I won't be doing any Fortran versions that are older than me. No thanks :-) – xebtl – 2015-04-16T07:34:02.997

6

1987 - Perl

Perl is a high-level scripting language developed by Larry Wall in 1987. He used it for processing his reports, which has lead to the backronym Practical Extraction and Reporting Language (but Perl is not, in fact, an acronym for anything).

It’s based on Unix shell programming, and you can see features of that in the language: for example, all variables have a sigil, and it has builtins that mimic common shell commands.

The original 1.0 source code was posted to a newsgroup in December 1987. The current stable version is Perl 5, which began life in 1993, and has had incremental new versions ever since. A specification for Perl 6 was started in 2000, but it does not have an official implementation, and it is sometimes said that Perl 6 is vapourware.

Perl is often derided for its heavy use of regular expressions.

I tested my code on Perl 5, but I believe this is all vanilla Perl and should work on any version.

Task 1

This could be done as a one-liner, but I thought it worth demonstrating sigils (the dollar signs) before variable names.

sub task1
{
  $language = "Perl";
  $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";
}

alexwlchan

Posted 2015-04-06T05:54:55.230

Reputation: 637

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

6

1978 - MATLAB

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

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

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

Task 1

'MATLAB was made in 1978'

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

Task 2

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

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

Task 3

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

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

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

Puzzled

Posted 2015-04-06T05:54:55.230

Reputation: 81

You need to change your answer some bit, Your title is not as OP want, You used ** instead of # Also First task show mathematica instead of matlab. – kuldeep.kamboj – 2015-04-20T10:13:51.713

@kuldeep.kamboj the first task does work in matlab also. The format is only a bit settings dependent. If you want to have settings independent format then you can use: fprintf('Matlab was made in 1978\n');

Like I wrote. – Puzzled – 2015-04-20T17:11:21.787

1I don't know what was the functionality of first version of Matlab, but Task 2 is a serious overkill. The sequence t=eye(n); t(:,1)=t(:,end)=1; t*='N'; t(t==0)=' '; disp(char(t)); does the job perfectly. The syntax of the first Matlab might be a bit different, but it must have had some "matrix" operations. Yet replacing loops for matrix operations is so obvious in Matlab, there are even functions created to easily replace a bunch of vector operations into a single matrix one (vide repmat). – pawel.boczarski – 2015-04-20T23:23:50.307

Agreed on that fact. But given that the first version of matlab was that long ago, I'm quite sure the syntax was widely different back then (for example might not have had splicing ":" etc). For that reason I decided to use loops. (Otherwise I'd have to know the library reference for the first Matlab) – Puzzled – 2015-04-22T07:17:27.160

5

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;

refi64

Posted 2015-04-06T05:54:55.230

Reputation: 7 567

5

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.

refi64

Posted 2015-04-06T05:54:55.230

Reputation: 7 567

5

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.

Task 1

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

gcd1 (m, n) := if n = 0 then m else gcd1 (n, mod (m, n))$

alephalpha

Posted 2015-04-06T05:54:55.230

Reputation: 18 628

5

1976 - SAS

Language History

SAS, previously an acronym for Statistical Analysis System, was developed at North Carolina State University from 1966 to 1976 by Anthony Barr, a professor at NC State, and James Goodnight, a student at NC State. The SAS Institute was incorporated in 1976, when it released the first commercial version of SAS, which was a redesign of the original version developed at NC State.

The language's syntax was based on PL/I, and indeed the internals were originally written in PL/I. However, the internals have since been rewritten in C.

Once the reigning king of commercial statistical software, in recent years interest in SAS has waned, giving way to languages like R and Python. The reasons for this are numerous, including the fact that a single user license for SAS can cost upward of $10,000 USD annually whereas R and Python are free, and SAS is strictly and vehemently closed source while R and Python are open source. However, though it's struggling to remain generally relevant, SAS still maintains a stranglehold on the world of FDA-regulated clinical trials.

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

Alex A.

Posted 2015-04-06T05:54:55.230

Reputation: 22 170

5

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#

xebtl

Posted 2015-04-06T05:54:55.230

Reputation: 886

Did you intend to leave the PRINT a," ",b? Seems like it was for debugging purposes. – refi64 – 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

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)

marinus

Posted 2015-04-06T05:54:55.230

Reputation: 29 024

4

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.

marinus

Posted 2015-04-06T05:54:55.230

Reputation: 29 024

4

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

DLosc

Posted 2015-04-06T05:54:55.230

Reputation: 17 064

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.

kuldeep.kamboj

Posted 2015-04-06T05:54:55.230

Reputation: 595

1For gcd, why the if [ "$a" -ne "$b" ] check? Seems to me that gcd 8 8 should be 8, not 0. Also, the logic to determine large vs small is actually unnecessary: if the first step performs $small % $large, the only effect is that the numbers get swapped; therefore, on the next iteration they will be in the proper order. – DLosc – 2015-04-16T15:41:13.340

Hmm I think their are other optimized ways to get GCD but that is one I found on checking out on net in PHP. I convert code it to bash. – kuldeep.kamboj – 2015-04-16T17:38:56.660

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

@marinus, You always can post solution as OP state that better answer in same language can be posted. If this is stackoverflow/programmers stack exchange I obviously go for better solution. But requirement of this question to write three program for particular language introduced in year. – kuldeep.kamboj – 2015-04-18T05:19:20.203

I can't, I've already posted an answer for 1992 so I can't answer for 1989. – marinus – 2015-04-18T05:22:56.087

4

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

kuldeep.kamboj

Posted 2015-04-06T05:54:55.230

Reputation: 595

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

pmarflee

Posted 2015-04-06T05:54:55.230

Reputation: 171

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)    

pmarflee

Posted 2015-04-06T05:54:55.230

Reputation: 171

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

Wightboy

Posted 2015-04-06T05:54:55.230

Reputation: 321

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

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

bacchusbeale

Posted 2015-04-06T05:54:55.230

Reputation: 1 185

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 &lt;iostream&gt; 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