Hacker News new | comments | show | ask | jobs | submit login
A Universe in One Line of Code with 10 PRINT (makeartwithpython.com)
261 points by burningion 8 months ago | hide | past | web | favorite | 135 comments



This has me reflecting on how I learned to program, compared to how people learn to program today.

I learned to program using BASIC when I was between 5 and 10 years old. My dad was a software engineer at DEC, and he had a kit computer in our basement that he let us play with once in a while. My first program was a number-guessing game, and it went something like this:

    10  NUMBER = 23
    20  PRINT "I'm thinking of a number."
    30  INPUT "Make a guess: " $GUESS
    40  IF GUESS < NUMBER THEN
    50    PRINT "Too low!"
    60    GOTO 30
    70  ELSEIF GUESS > NUMBER THEN
    80    PRINT "Too high!"
    90    GOTO 30
    100 PRINT "You got it!"
That was pretty straightforward, because everything about it was linear except for the GOTOs. You can think about each step with very little planning, and when you need a break in program flow you can use a GOTO. It also means when teaching, you can introduce each new concept as the need arises: store a value, print a statement, prompt for input, check a condition, and go back to a previous statement.

Let's see the same program in Python:

    number = 23
    print("I'm thinking of a number.")

    guess = 0
    while guess != number:
        guess = input("Make a guess: ")
        guess = int(guess)
        if guess < number:
            print("Too low!")
        elif guess > number:
            print("Too high!")
        else:
            print("You got it!")
The overall program logic isn't much different when you read the code. But to write this code, you need to know a number of things in advance. You need to know how you're going to approach the problem. You need to know what a loop is, and specifically what a while loop is. Conceptually, especially for a young person, a while loop is much more abstract than a GOTO statement.

I am happy that people get to learn a language like Python as their first language today. They can do much more interesting things, in a shorter amount of time, than they could in basic 40 years ago. But the very first programs people write seem fundamentally different, and that's not a bad thing.


Very well put. I remember writing gotos everywhere when I learnt to code. Interestingly enough my first program was almost the same as yours. Great thing about a goto is that it is a single command which can emulate any of the other constructs.

Also one thing I remember from back when was that if there was a problem I did not understand (I was mostly learning by modifying example programs that I somehow got) the only way to solve them was to try more things and harder. I did not have any books and internet was a luxury. Eventually I have understood more of the code and got better.

Nowadays it is way easier to remain ignorant and still be productive.


> Great thing about a goto is that it is a single command which can emulate any of the other constructs.

The thing is BASIC does have other constructs. GOSUB[0] has been around in the 70s and that worked like a GOTO except when a RETURN statement was hit the code would then jump back to the point where it GOSUB'ed - effectively behaving as a rudimentary subroutine (hence the name, "GoSub").

There was also the FN[2][3] statement that allowed you to write basic functions, albeit you were limited to 1 liners. But by the 80s some dialects of BASIC were supporting more complex procedures[3][4].

[0] http://www.hoist-point.com/applesoft_basic_tutorial.htm#stri...

[1] http://www.cpcwiki.eu/index.php/Locomotive_BASIC#FN

[2] https://www.c64-wiki.com/wiki/FN

[3] http://www.bbcbasic.co.uk/bbcwin/tutorial/chapter16.html

[4] http://www.bbcbasic.co.uk/bbcwin/tutorial/chapter17.html


Also, didn't the FOR..NEXT loop show up really early on?


Yup. Also WHILE/WEND loops and some basic error control with ERROR (raise), ON ERROR (capture).

BASIC certainly had it's faults but it was a reasonably complete language. However it can't have helped the number of different dialects there were in the 70s and 80s. Each brand of consumer electronics seemed to ship with a subtly different list of statements which meant I think lead people to often stick with the core basics of, erm, BASIC.


Pretty sure WHILE/WEND was a slightly later addition.

I just went and looked up Dartmouth BASIC (this is the original thing). The list of keywords shows FOR, but not WHILE. This is the manual for v2, as early as I could find (1964) - it also has FOR already, but not WHILE:

http://www.bitsavers.org/pdf/dartmouth/BASIC_Oct64.pdf

(Side note: it's kinda amusing that the document uses a slash-through to distinguish the letter O from zero, except it does it in a way that is reverse of what is common today: it's the letter that has a slash through it!)

I do wonder if it was a true loop, though, or whether it was implemented more along the lines of GOSUB/RETURN (i.e. whether FOR basically set up a dynamic label, and NEXT did an indirect jump). If so, then it should be possible to have two FOR statements with the same variable, both "matched" to a single NEXT, if GOTO is used to reach it from one of the loops.


Ahh sorry, I was talking in the context of the microcomputer era of the late 70s and 80s rather than the full history of BASIC.

Thanks for the PDF, that will make really interesting lunch time reading :)

> I do wonder if it was a true loop, though, or whether it was implemented more along the lines of GOSUB/RETURN (i.e. whether FOR basically set up a dynamic label, and NEXT did an indirect jump). If so, then it should be possible to have two FOR statements with the same variable, both "matched" to a single NEXT, if GOTO is used to reach it from one of the loops.

I could be wrong here but I think most high level structures (switch, for loop, etc) end up getting translated to GOTOs at the machine level anyway. So you might be right with regards to the BASIC interpreter.

As for whether you could have fun with that, Dartmouth is before my time but I remember Locomotive BASIC (Amstrad CPC 464, so we're talking early 80s) used to do run time checks to ensure you weren't abusing NEXT inside nested FORs.


I tried it on QBASIC and Turbo BASIC, and both require matching FOR and NEXT. Now I'm really tempted to set up a Dartmouth emulator to see if it was also true there...


It was in Integer BASIC and Applesoft BASIC on the Apple II. You could say something like this to count to 10:

    10 FOR I=1 TO 10
    20 PRINT I
    30 NEXT I


> I am happy that people get to learn a language like Python as their first language today. They can do much more interesting things, in a shorter amount of time, than they could in basic 40 years ago.

How much is down to the language and how much is that to do with the capability of computers then vs now. A fair few dialects of BASIC could manipulate the hardware directly but the capability of those machines were always quite limited. However with the hacker community going strong for retro hardware, you can now get all sorts of cool mods, like the WiFi addon I have on my Amstrad CPC 464 which allows me to even make HTTP GET requests, from BASIC. Ok I'm still limited by 64K of memory but that just forces you to think more creatively.

I'm not denying that Python teaches better programming principles than the early dialects of BASIC, but again how much of that is down to age given than newer dialects of BASIC can be structured very much like a typical imperative program. ie no requirement for line numbers, proper functions (though some dialects of BASIC have supported this since the 80s), etc.

Sometimes though, I think the simplicity of your environment can count for a lot. I remember reading an interview with a dance DJ turned producer who commented that he regretted buying lots of hardware when he was starting out as it slowed his learning curving (too much tech to learn in one go) and thus he would have been better off buying one synth, mastering that, then moving onto another synth. I wonder if programming can be like that for youngsters these days. I wonder if they get crippled by the vastness of the options out there and all the layers of the stack involved in even the simplest of "Hello world!" programs. Yet BASIC on the micro computers of the 70s and 80s offered a simple, no hassle, interface to that allowed our young imaginations to fly. I think we were very lucky to grow up in that era.


Defo, my Mum's partner had an Atari ST with cubase etc. and a couple of keyboards and he used to have fun and make music. Ever since he bought his first PC, he has made no music whatsoever, he spends his time in the Internet wormhole and optimising his hard drive (no kidding). Very easy to focus on your tool set and not actually use them.


Hehe the guessing game was my fist too, way before I even had a computer.

I think what we have lost from the old 8-bit computers and their BASIC, was the ability to instantly have something show on the screen, like the classic Sinclair Spectrum spider web:

    10 FOR n=0 TO 31
    20 PLOT n*11,0
    30 DRAW -n*11, 175-n*8
    40 NEXT n
(or something like that) That stuff got me hooked.


You can get pretty close to that with JavaScript, especially with all the CodePen-like sites out there -- but even without those, the JavaScript console is pretty similar to the old BASIC prompt in terms of immediacy and ubiquity.

JavaScript also has this in common with BASIC: the language bigots hate it. :-)


I like BASIC, C, D, Objective C, Perl, Lua, 8080 and x86 Assembly (no code for around 15 years, but still) and probably few others catched my eye, like Io, LISP, Haskell, but I had no time to master these, only done a bunch of snippets discovering their power. But I hate js (and php) with all of my soul’s strings, no matter how much time I spent learning or fixing it. How about that single data point.

Otoh, I bet most js bigots only know one language very good, guess what it’s name is.


Indeed! I defended JS for this exact purpose after the 2D canvas became truly ubiquitous. Still a minor amount of boilerplate but you can be drawing stuff in no time. With an integrated editor it would be perfect!


Python still has Turtle in its standard library, with which you can create direct and simple graphics like you describe.

https://docs.python.org/3/library/turtle.html


There is also a thing called Logo (http://www.softronix.com/logo.html); that implementation is windows-only and old, but it was a glorious first programming language for me. There is also a unix version called ucblogo, but when I tried that a while ago on mac, it was terribly slow and didn't have a number of the nice additions that mswlogo had.


For people looking through the archives: FMSLogo is an updated version of MSWLogo, and is linked to from the same page. It runs beautifully under Wine, too, so not being on Windows is no excuse for not trying it out. ;)


Fun fact: LOGO is a LISP.


This is a niche I think Scratch (https://scratch.mit.edu/) does a pretty good job of filling


And if I remember right, on some Spectrum model you even had all the basic commands written on keys (I was once hunting with a friend for the famous "any" key which we had determined had to be pressed in order to get to play Pyjamarama)


Your code does not work for me. I get syntax error in line 20: https://imgur.com/a/mqI29. What did I do wrong and how can I get it to work?


It's for the ZX Spectrum: https://imgur.com/a/Yb757

There's a Javascript emulator here: http://jsspeccy.zxdemo.org/

128K mode is easier because it lets you type the keywords instead of pressing single key shortcuts. For the punctuation, type:

ctrl-l for =

ctrl-b for *

ctrl-alt-n for ,

ctrl-j for -


I learned exactly this way, with GWBASIC, with the same program. It's why I chose this program as the start of "The Rust Programming Language", honestly. Similar to your point about Python, it's more complex. Then again, so are computers...

I'm lucky enough to still have the book for my first computer, my second encounter with BASIC. I tweeted some photos of it last year https://twitter.com/steveklabnik/status/721471207883808769


By introducing a couple of functions: say() and audio_input(), you could make it into a talking game:

  number = 4
  say("I'm thinking of a number")
  while True:
      try:
          word = audio_input("Make a guess: ").lower()
      except RuntimeError:
          say("Try again")
      else:
          say(word)
          guess = word2num.get(word)
          if guess is None:
              say("Not a number")
          elif guess < number:
              say("Too low!")
          elif guess > number:
              say("Too high!")
          else: 
              say("You got it!")
              break
Complete code example https://gist.github.com/3b3f26602e31198d399c643c8053b8b6


I've learned my BASIC with Turbo BASIC on DOS, which already had WHILE/WEND. I don't recall any trouble with this concept.

When I moved on to QBASIC, which had a wonderful DO..LOOP construct which generalized loops with positive and negative pre- or post-conditions, also allowing for no conditions at all, it was really awesome and just felt "right".

I also remember how befuddled I was by GOSUB/RETURN, having seen it after learning DEF FN and SUB. The idea that you could just fall through the "end" of a procedure by not returning from it seemed nuts.


I don't see these programs as fundamentally different. The only material different is that one uses a GOTO and the other uses a while loop.

But I don't think either of these is more intuitive. When you learnt how a GOTO works, you probably learnt immediately afterwards how to use it to loop. This loop is a 'pattern', one which you would have to grok as a single idea before you could write a program like the above. This is similar to learning about a while loop, and then knowing you would need one when you wrote the Python script.


I think this snippet is missing either ENDIF at 95 or the fact that

  IF ... THEN <x> ELSE <y> 
accepts either a single statement or a line number to go to as <x> and <y>. So, in dialects where ENDIF doesn’t exist at all, it was actually a bit harder than just writing or thinking WHILE-style. When I moved from ZX spectrum-clone basic to gwbasic and tbasic/qbasic, it felt much easier. (I was also more advanced by the time, so can’t tell how it changed my view on the old style.)

Edit: formatting


I also learned to program in BASIC, but I learned by creating games on the TI-83+ graphing calculator. The limited nature of the platform led me to learn quite a lot in addition to the basics: performance optimization, garbage collection, matrices, lists, UX, maintainability, keyboard shortcuts, and how to read documentation.

Would I recommend this platform to someone else? Only if they needed to learn to program while pretending to do math homework.


My first programming course was in fortran and i got away without using alot of built in loop logic using goto statements.

Now i never use any goto statements ever


I'm pretty sure you can write the program in BASIC without GOTOs. Doesn't BASIC have WHILE loops?


In the distant past, when I was an undergraduate at Wits University in Johannesburg (around 1970), someone discovered APL and they posted a 1-line APL program that printed the multiplication matrix for all numbers from 1 to 10. This lead to a flurry of postings on the (real!) bulletin board, but the show-stopper was a very short program written in IBM Assembler language, using macros. The code was written by a brilliant physicist named Colin Marquard who also single-handedly re-wrote (in assembler!) the so-called time-sharing system that we used for our courses. (IBM selectric typewriters connected by a proprietary network to the 360). Colin later had to flee South Africa (see, for example, https://goo.gl/Hw3WWb) because of his anti-apartheid activities.


I also found this: http://www.catb.org/jargon/html/O/one-liner-wars.html about APL one-liners


For the python example, instead of using "\" and "/", you could just use the PETSCII characters that the original 10 PRINT as they were ported to unicode.

This is my version

  python3 -c "while 1: print(chr(int(9585.5 + __import__('random').random())), end='')"


I tried a JS version, but first I locked my browser window (lol, while (true)), then used console.log which in a browser will always do a newline and deduplicate double logs, then used a string concatenation and the result just isn't as interesting, nor the code as sexy. Note also that ascii codes are different, so no magic with floats and such.

    var str = ''
    for (var i = 0; i < 1000; i++) {
      Math.random() > 0.5 ? str += '/' : str += '\\'
    }
    console.log(str)


Geez I feel old when I read a post where the OP feels the need to explain how BASIC works !

It's kind for those who weren't there at the time (and is a logical thing to do)

Where are those 30 years gone :) ?


Understood it because it looked like the code for my childhood calc (TI 83 :p)


I'm sure you could show this post 40 years from now, people will still understand it from programming their TI-83 in high school.


Programming on a TI-83 will be a thing as long as TI-83/4s remain the "gold standard" of graphing calculators in high school.


Seriously, is there a good graphing calculator app for Android that gives you all the same functionality but runs on modern hardware? I've been out of high school for 20 years I don't care what's prohibited in exam rooms.


I remember my AP Calculus exam. We were allowed graphing calculators. So I wrote a basic program that gave all the formulas, notes and tips we could come up with in a stupid version of less. Totally legal, we were allowed calculators with whatever programs we wanted. The just didn't think someone would make a program that was nothing but hundreds of PRINT statements!


I had no concept of computer programming growing up. It was playing around with my TI-84 around junior year of high school that exposed me to it. I saw the PROGRAM button so I looked in the calculator manual and started writing TI-BASIC. I told my precalc teacher about it and she looked at me funny. She had no idea you could write programs on graphing calculators. I will always appreciate my TI-84.


Some of my teachers required you to use the school-owned calculators, which were cleared after every class. Other teachers specifically allowed you to use your own programs during class.

I think that it was pretty common for students to trade programs around, so most of the teachers knew that the calculators were programmable.


My high school precalc textbook actually walked you through the process of writing a simple quadratic formula solver program. By this time, I had actually already gotten into writing TI-BASIC (as the first time I really started learning to program, failing to wrap my head around both python and C before) and I had created a slightly more complicated formula program with input sanitization and error handling, as well as a few other silly formulas. After this chapter I started passing around this program, as well as a small game I had written. These things were probably the most recognized I will ever be for my code, and I still have both programs.


Exactly the same story here. I really enjoyed my time tinkering with the TI-84.


Yeah ! School was so boring, programming calc is what got me into computer science. I'll never forget all my programs for IFS fractals, Syracuse suite visualization, Tic Tac Toe, Minesweeper...


TI-83 version of BASIC was the first exposure to programming I ever had. My friends and I made text-based RPGs on our calculators and swapped them to play each others' during classes.


Anyone remember HTA? https://technet.microsoft.com/en-us/library/ee692768.aspx

It seems oddly familiar, don't you think?

Thinks change so much!


HTAs are a subset of MS's Visual Basic Script language with a smattering of built-in HTML support.

If you are a masochist, it's entirely possible to write a full application as a HTA. I once had to do this when I needed to explore an organisations Active Directory, but they wouldn't install the AD Admin tools on my Laptop, or give me local admin. (For those that know AD, it was a 'Users & Computers' clone written entirely in HTA. I used Notepad as my IDE)


This reminds me of another great article.

http://www.learningclojure.com/2010/09/graphics-like-its-197...

The author talks about how its harder to get graphics on the screen without installing prerequisite software than it used to be, and goes on to sing the praises of the ZX Spectrum and its concise and well written manual. He finishes the article with some fun coding experiments writing Clojure code in the spirit of the ZX.


Xterm has tektronix mode which is somewhat similar. Try:

  xterm -t -e 'curl https://raw.githubusercontent.com/joejulian/xterm/master/tektests/usmap.tek ; sleep 10'


oh wow, that's pretty cool


Xlib is trivially easy to use if you're willing to use C. Slightly harder (but also satisfying if you have serious NIH) is the /dev/fb interface.

And there's sixel if you're using a terminal like mlterm.


Funny, I've often heard X programming described as 'not trivially easy'.


Maybe doing widgets is hard? If you just want to draw shapes on the screen there honestly isn't an easier way to do it.


If you are not too picky, there's always JavaScript and Canvas.


That's "without prerequisites" nowadays? Interesting. In my world, this requires installing one of the most complex pieces of software in existence (a web browser, plus its dependencies), on top of a graphical OS (also a highly complex network of interdependencies).


> In my world, this requires installing one of the most complex pieces of software in existence (a web browser, plus its dependencies), on top of a graphical OS (also a highly complex network of interdependencies).

In most people's world (where "most" is probably > 95%), their computer comes with those things already installed.


Complex architectural stacks have costs beyond install in most people's world: how many layers of indirection between &lt;canvas&gt; and actually drawing on the screen? That's a lot of cycles spent doing busywork.


Yeah, but installing a browser is easy, compared to setting up depends for other environments.


There's the same implied prerequisite as with BASIC: you need a personal computer. I mean, you seem to know how to uninstall the browser from your laptop, but is not doing that a meaningful prerequisite?


or just straight DOM:

javascript:for(i=4051;i--;)document.write(i%~80?'&#'+(9585+new Date%i%2):'<p style=margin:-.5em>')


I'm teaching 11-year old boys to do graphics in Python using the turtle module. It's pretty easy.


There's an interesting book that uses that C64 one liner to "understand the cultural context of computing" and it's an open access book: https://mitpress.mit.edu/books/10-print-chr2055rnd1-goto-10


The opening line of the article is:

"10 PRINT[1] is a new book which explores the magical power of a single line of code."

[1] https://www.amazon.com/10-PRINT-CHR-205-5-RND-ebook/dp/B00C9...


I got a hardcover of this book when I bought a used C64 off eBay. I was hoping to see it mentioned!


Exactly what I was going to say. It's apparently part of an MIT Press series of books on "Software Studies", a kindof humanities approach to software.

> The Software Studies book series, published by the MIT Press, aims to publish the best new work in a critical and experimental field that is at once culturally and technically literate, reflecting the reality of today’s software culture.

The entire 324 page book can be downloaded as a pdf at the above link.


I dunno what the need for using pygame was if the goal was to replicate this you could just use print in the REPL with a loop or recursion


The Commodore 64 version has square characters that are close to being aligned with each other. You can get the same characters output in a few lines of Python, but you can't replicate the look unless you make a careful choice of font to render it in. The output from the REPL with my normal terminal font looks like a bunch of characters more than it does a randomly-generated maze. The visual connection just isn't there.


One can also do better with the right choice of characters: ╲ ╱

  from random import choice; print(''.join(choice(('╲', '╱')) for i in range(10000)))


You can match the spirit of it pretty closely with Perl.

perl -C -e '$|++;X:print chr(9585.5+rand());goto X'


PHP too

    php -r "TEN: print(chr(47 + 45 * rand(0,1))); goto TEN;"


Why "9585.5", is that a particular unicode character? That only displays squares on my terminal. I've tried to replace this with 205.5 like in the example but that would only display Î or Í.


9585 is ╱ 9586 is ╲ (both mentioned elsewhere in the thread by their hex equivalents 2571 and 2572)

Try a different terminal maybe? Works in xterm, xfce, etc, for me. Also, I have LANG set to en_US.UTF-8

The ".5" is because Perl's chr() will convert it to an int by chopping off the decimal portion. rand() returns a floating point number between 0 and 1. That's very similar to what the BASIC program is doing.


I did this a while back and saved in a gist. I don't remember if it had any problems though.

s=╱╲;while :;do printf ${s:RANDOM%2:1};sleep 0.001;done


It would actually be doable in 2-3 lines using Unicode characters 2571 and 2572 (both hex), respectively "╱" and "╲".


  import sys, random

  while True:
      sys.stdout.write(random.choice([u'\u2571', u'\u2572']))
      sys.stdout.flush()
They're called box drawing characters, it's how ncurses applications draw their GUI.

https://en.wikipedia.org/wiki/Box-drawing_character


# Without unicode or pygame (using Python3)

  import sys, random
  while True :
    print( random.choice( [ chr( 92 ) , chr( 47 ) ] ) , end = "" )
    sys.stdout.flush( )


  import random
  while True:
      print(random.choice("╱╲"), end="")
How's that for readability?


That's cool, didn't realize HN would allow that.


Here's a smaller one:

python3 -c 'while True: print(__import__("random").choice("╱╲"), end="")'


This one doesn't look correct in the terminal though as the characters don't join up

(parent):

  ╱╱╱╲╲╲╲╲╲╱╲╲╲╱╱╱╲╱╱╱╲╲╲
  ╱╱╲╲╲╲╲╲╲╲╱╱╲╲╲╱╲╲╱╱╲╲╲
vs (yours)

  \\\/\\\//\//\\///\\\\////\
  /\////\\\//\\\/\/\/\\\\/
Also in the terminal there isn't the space between the lines for the parent either (that's just HN formatting), but there is a space when using \ or /


The C64 font is (almost?) square, this also contributes to the nice effect.


It's square as it's 8x8 pixels, but the pixels themselves are not. There's a difference in aspect ratio between PAL and NTSC variants, and because the C64 was usually connected to a CRT, pretty much all bets are off.


That's because of HN formatting.


It's because u'\u2571' is a different character from chr(92)


Why flush?


In some terminals, python buffers the output until it has enough and then dumps it to the console. IIRC it is like this because the console can be pretty slow, so by buffering you can do more calculations instead of always waiting for the console.


It should always flush at the end of the line though, no?


I initially put a sleep in, it's unnecessary in this case.


    (loop (princ (char "╱╲" (random 2))))
... or, if you use alexandria (a popular set of utilities)

    (loop (princ (random-elt "╱╲")))


They definitely didn't succeed in reviving the magic of that one-liner. I could see myself explaining the BASIC code to my little brother, but when it comes to the new version I don't think I would succeed.


Speaking of one-liners, this one is pretty cool: https://twitter.com/isislovecruft/status/447568252223647744


Hi! One of the authors of 10 PRINT here.

You might enjoy this browser-based graphical variation. Many people also made Processing-based variations, too:

http://diydsp.com/fun/10print/10_print_param.html


Hi diydsp ! Do you still do low-level microcontrollers audio hacking ? kudos for that clever art generation !


Hey makapuf! Good to see you here!!! I'm mostly using a color these days and spending time on the rest of the instrument! See http://dsp.guitars for example!


Very Interesting !


I too cut my programming teeth in BASIC, first on my brother's Challenger 1P and then on my very own CoCo I. While it was fun being closer to the metal I'd much rather of had the 16GB laptop connected to the 43" monitor that I have now at 46 when I was 8.

btw, you can get pretty close to the spirit of the code with just a few more lines of Javascript:

    var col = 0;
    setInterval(() => {
      document.body.innerHTML += String.fromCharCode(47+(Math.round(Math.random())*45)) + (++col % 80 ? "" : "<br/>")
    }, 10);
or if you want to code golf you can get it into 1 line:

    var col = 0, fn = setInterval(() => {document.body.innerHTML += String.fromCharCode(47+(Math.round(Math.random())*45)) + (++col % 80 ? "" : "<br/>")}, 10);
You can see it in action here:

https://jsfiddle.net/x5mz341z/

(edited to point to new jsfiddle with css body rules)


You could golf it down a bit more with:

document.body.innerHTML += (Math.random() > 0.5 ? "\\":"/")


doesn't really work with a proportional font.


Agreed - I created a new jsfiddle with a couple of body style rules and updated the link.


created a new fiddle taking various suggestions through the post...

https://jsfiddle.net/tj1zwqat/

interesting that it renders perfect ( for me ) in chrome, and a bit of an offset in firefox

js

setInterval(() => {document.body.innerHTML += (Math.random() > 0.5 ? "╲":"╱")}, 1)

css

body { line-height:1em; max-width: 500px; word-wrap:break-word;}


For those interesting what “; :” is, “;” is print’s command syntax for not putting a newline, and “:” is a command separator. Old basics were lexically rich, e.g. box drawing looked like:

  LINE (x1, y1) - (x2, y2), 2, BF
[B]ox, [F]ill


Newer BASICs were, too. In fact, the statement you wrote above was still valid in Visual Basic 6.0, provided that it was inside a method in a form (window) - in which case it drew the line on that window. If you wanted to draw it on another one, then you had to use the dot-syntax, but the rest of it would be the same, e.g.:

   otherForm.LINE (x1, y1) - (x2, y2), 2, BF
Curiously, LINE was an actual method, with regular parameters; it's just that it had this irregular syntax when calling it. VB had a bunch of special-cased rules for some identifiers like that, for back-compat reasons. Pretty much anything you could do in QB, you could do in VB - CIRCLE, PSET etc.

https://msdn.microsoft.com/en-us/library/aa230480(v=vs.60).a...

This all got ditched in VB.NET in favor of a regular syntax.

But my favorite part in old BASICs was that the function MID$() - which in other languages is usually known as "substring" or "substr" - was special-cased so that it could be used as target of assignment. So:

   s$ = "foobar"
   PRINT MID$(s$, 2, 3)   ' oba
   MID$(s$, 1, 2) = "uu"
   PRINT s$               ' fuubar
And yes, VB has this, too. In fact, even VB.NET does (although it did away with $).


When BASIC needs to be explained. Is it everyone else, or am I just getting old? :’(


I remember a one-liner in BBC basic that gave you the snake game.

I wish I could see that again. Not sure if it was in one of the old acorn electron mags.

It seemed like magic, did some pretty low level stuff.


I'm one of the lucky people who got to type that line into the C64 basic console as a kid back in the 80's. Then I played the Great Giana Sisters.


This single line code

    {def U1 {lambda {:n} {if {< :n 0} then else {if {< {floor {* {random} 2}} 1} then ╲ else ╱} {U1 {- :n 1}}}}} {U1 1000} 
draws the labyrinthic universe in any web browser. See http://lambdaway.free.fr/workshop/?view=U1


This is a smaller one:

   {map {lambda {_} {if {< {floor {* {random} 2}} 1} then ╲ else ╱}} {serie 1 2000}}


Two favorite programs of my childhood:

  10 REM drawing a galaxy
  20 FOR r=1 to 50
  30 CIRCLE 150, 100, r
  40 NEXT r
  50 ...


  10 REM playing a song
  20 BEEP 1,0: BEEP 1,2: BEEP .5,3: BEEP.5,2: BEEP 1,0
  30 ...



One line Tetris in Acorn BBC Basic:

https://survex.com/~olly/rheolism/dsm_rheolism/


Nice to get a shout out with the GIF credit from my YouTube video. After I saw Casey Reas speak at Eyeo about the 10 PRINT book, I recorded that with Vice. While the other authors made a version, Slate for some reason used my version, and it was my 15 minutes I guess, heh. It is a great book, and I still flip through it now and again. This is a great post, and I have a lot of fondness for the C64 from when I was a kid.


I still remember my very first program. It was similar to the maze, but "animated":

10 PRINT "";

20 PRINT " ";

30 GOTO 10

If you choose the right # of *'s and ' 's you get a series of diagonals moving across the screen (since the semicolons prevented the carriage return). For me, the impression of travelling along a bridge was completely captivating, and I was hooked on programming ever since.


Cool. Looking at this closer, I realized this doesn't create a maze with multiple branching paths. It creates just linear paths.


Same program in Lobster (a Python-alike statically typed language with built-in graphics): https://github.com/aardappel/lobster/blob/master/lobster/sam...


I have a strange feeling of synchronicity, I saw this code for the first time only this morning on the 8bit guy's YT channel, looks like this page just pre-dates that video though. https://youtu.be/KAivGLHJzJM?t=18m54s


Does the random number generator in C64 basic start with the same seed? I know the QBasic rand function was horrid.


In QBasic you had to put a RANDOMIZE TIMER statement to get a different seed whenever you run.


Yes, I remember when they demonstrated this to us in elementary school with C16-s. It's clock based IIRC :)


I remember doing it on my Vic-20, and I had done ASCII graphics on my Commodore PET in 1978! I had a thermal printer for my Vic-20 the width of receipt paper. I wrote a program from an astronomy calculation book to show where the 4 major moons of Jupiter were on an almost line due to their orbital planes being parallel to our line of sight here on Earth. So much easier to just get going with stuff then from bootup. It's why I like the interpreter that comes with J (jsoftware.com). Rosetta almost-one-liner for the Sierpinski triangle in J:

  load 'viewmat'
  'rgb'viewmat--. |. (~:_1&|.)^:(<@#) (2^8){.1


This reads like a parody of Pygame. Why write something in a single line of Commodore Basic when you can do it in 50 lines of Python?


This is "a hello world for pygame", not "PRINT 10 for python".


You can do it pretty easily in the terminal using Python too, I don't really know what they needed pygame for.


I get downvoted a lot for this kind of comment every time, but I can't help it. (more proof that this is a trend) Here we go:

"Hey guys here's a short program demonstrating something"

....

"with python"

!!!!


I did exactly that in about 1978 on the Commodore PET and showed it at a meeting.


Title should be 'A Universe in One Line of Code with PRINT' because 10 is just the line number.

Line numbers are used in console BASIC to reference and edit a line, it normally doesn't have a screen editor.


Neither a game nor a single line (using semicolons is disingenuous)


This might vary by language, but in the ones I'm familiar with, the culture of "one-liners" has always permitted multiple statements on the line with statement separators. E.g. the awk one-liners: http://www.pement.org/awk/awk1line.txt (similar for Perl and shell).


Okay, fair enough. I'll grant you this.

But this certainly doesn't fit in one line by my standard. It linebreaks in my standard tiling setup. `from random import choice; print(''.join(choice(('\\', '/')) for i in range 10000)))`


In Julia:

    while true; print(rand(Bool) ? '╲' : '╱'); end


Or Powershell:

  While ($True) { Write-Host (Get-Random '\','/') -NoNewLine }


elixir one-liner:

    for _ <- 1..1000, do: IO.write Enum.random(["\u2571","\u2572"]); IO.write "\n"


I'm impressed C64 Basic had floating point!


Interesting, thanks for sharing this.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: