We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.
NeverGonna
NeverGonna is an esoteric programming language that is designed to look like the famous song "Never Gonna Give You Up".
Syntax
To declare a variable named foo with the value of 2:
we're no strangers to foo gotta make foo 2
To make an if statement checking if foo == "orange", using a user input:
we're no strangers to foo
gotta make foo your heart's been aching but you're too shy to say 'Please type in "orange"' -- get user input
inside we both know foo == "orange" then -- if statement
i just wanna tell you "You did it!"
never gonna let you down -- else
i just wanna tell you "You failed."
never gonna give you up -- end
To add two numbers into a variable named bar:
we're no strangers to bar gotta make bar foo + 1
To make a for loop that prints the numbers 0 through 10:
we're no strangers to foo
gotta make foo 0
we've known foo for 10 -- for loop
i just wanna tell you foo
never gonna give you up -- end for loop
To make a while loop
we're no strangers to foo
we're no strangers to bar
gotta make foo True
a full commitment's what I'm thinking of foo -- while loop (while foo)
gotta make bar your heart's been aching but you're too shy to say 'Please type in "orange"'
inside we both know bar == "orange" then
gotta make foo False
never gonna turn around bar == "" then -- elif
i just wanna tell you "You didn't type anything."
never gonna let you down -- else
i just wanna tell you "You didn't type orange."
never gonna give you up
never gonna give you up
i just wanna tell you "You did it!"
The language's syntactical aspects shall be elucidated in an Extended Backus-Naur Form (EBNF) description:
program := { innerEmptyLine }
, { innerCommandLine | innerEmptyLine }
, [ lastCommandLine | lastEmptyLine ]
;
innerEmptyLine := [ comment ] , newlines ;
lastEmptyLine := [ comment ] ;
innerCommandLine := statement , [ comment ] , newlines ;
lastCommandLine := statement , [ comment ] ;
comment := "--" , { character - newline } ;
statementList := { statementListItem } ;
statementListItem := { innerEmptyLine }
, [ innerCommandLine ]
, { innerEmptyLine }
;
statement := varDeclaration
| varAssignment
| inputExpression
| printCommand
| ifStatement
| forLoop
| whileLoop
;
varDeclaration := "we're no strangers to" , varName ;
varAssignment := "gotta make" , varName , expression ;
printCommand := "i just wanna tell you" , expression ;
ifStatement := ifThenPart
, newlines
, { elseIfPart }
, [ elsePart ]
, endOfStatement
;
ifThenPart := "inside we both know" , expression , "then"
, newlines
, statementList
;
elseIfPart := "never gonna turn around" , expression
, "then"
, newlines
, statementList
;
elsePart := "never gonna let you down"
, newlines
, statmentList
;
forLoop := "we've known" , varName , "for" , expression
, newlines
, statementList
, newlines
, endOfStatement
;
whileLoop := "a full commitment's what I'm thinking of"
, expression
, newlines
, statementList
, newlines
, endOfStatement
;
endOfStatement := "never gonna give you up" ;
expression := booleanValue
| number
| singleQuoteString
| doubleQuoteString
| varName
| inputExpression
| unaryOperator , expression
| expression , binaryOperator , expression
| expression , relationOperator , expression
| "(" , expression , ")"
;
inputExpression := "your heart's been aching but you're too shy to say"
, expression
;
unaryOperator := "+" | "-" | "!" ;
binaryOperator := "+" | "-" | "*" | "/" | "%" | "^"
| "&&" | "||"
;
relationOperator := "==" | "!=" | "<" | "<=" | ">" | ">=" ;
varName := varNameCharacter , { varNameCharacter } ;
varNameCharacter := "a" | ... | "z" | "A" | ... | "Z"
| "_"
| digit
;
booleanValue := "False" | "True" ;
singleQuoteString := "'" , { character - "'" } , "'" ;
doubleQuoteString := '"' , { character - '"' } , '"' ;
number := [ "+" | "-" ] , digit , { digit } ;
digit := "0" | "1" | "2" | "3" | "4"
| "5" | "6" | "7" | "8" | "9"
;
newline := "\n" ;
newlines := newline , { newline } ;
optionalNewlines := { newline } ;
Commands
The arithmetic sign and logical NOT operators intrine to form the unary operation set:
| Operator | Operand | Effect |
|---|---|---|
+
| ||
| Boolean | invalid | |
| integer | plus sign | |
| string | invalid | |
-
| ||
| Boolean | invalid | |
| integer | minus sign | |
| string | invalid | |
!
| ||
| Boolean | logical NOT | |
| integer | invalid | |
| string | invalid |
The following binary operations, with respect to the possible operand type combinations, exist:
| Operator | Left operand | Right operand | Effect |
|---|---|---|---|
+
| |||
| Boolean | Boolean | invalid | |
| Boolean | integer | invalid | |
| Boolean | string | invalid | |
| integer | Boolean | invalid | |
| integer | integer | addition | |
| integer | string | string concatenation | |
| string | Boolean | invalid | |
| string | integer | string concatenation | |
| string | string | string concatenation | |
-
| |||
| Boolean | Boolean | invalid | |
| Boolean | integer | invalid | |
| Boolean | string | invalid | |
| integer | Boolean | invalid | |
| integer | integer | subtraction | |
| integer | string | invalid | |
| string | Boolean | invalid | |
| string | integer | invalid | |
| string | string | invalid | |
*
| |||
| Boolean | Boolean | invalid | |
| Boolean | integer | invalid | |
| Boolean | string | invalid | |
| integer | Boolean | invalid | |
| integer | integer | multiplication | |
| integer | string | string repetition | |
| string | Boolean | invalid | |
| string | integer | string repetition | |
| string | string | invalid | |
/
| |||
| Boolean | Boolean | invalid | |
| Boolean | integer | invalid | |
| Boolean | string | invalid | |
| integer | Boolean | invalid | |
| integer | integer | division | |
| integer | string | invalid | |
| string | Boolean | invalid | |
| string | integer | invalid | |
| string | string | invalid | |
%
| |||
| Boolean | Boolean | invalid | |
| Boolean | integer | invalid | |
| Boolean | string | invalid | |
| integer | Boolean | invalid | |
| integer | integer | remainder | |
| integer | string | invalid | |
| string | Boolean | invalid | |
| string | integer | invalid | |
| string | string | invalid | |
^
| |||
| Boolean | Boolean | invalid | |
| Boolean | integer | invalid | |
| Boolean | string | invalid | |
| integer | Boolean | invalid | |
| integer | integer | exponentiation, power | |
| integer | string | invalid | |
| string | Boolean | invalid | |
| string | integer | invalid | |
| string | string | invalid | |
&&
| |||
| Boolean | Boolean | logical AND | |
| Boolean | integer | invalid | |
| Boolean | string | invalid | |
| integer | Boolean | invalid | |
| integer | integer | invalid | |
| integer | string | invalid | |
| string | Boolean | invalid | |
| string | integer | invalid | |
| string | string | invalid | |
||
| |||
| Boolean | Boolean | logical OR | |
| Boolean | integer | invalid | |
| Boolean | string | invalid | |
| integer | Boolean | invalid | |
| integer | integer | invalid | |
| integer | string | invalid | |
| string | Boolean | invalid | |
| string | integer | invalid | |
| string | string | invalid | |
==
| |||
| Boolean | Boolean | equality | |
| Boolean | integer | equality | |
| Boolean | string | equality | |
| integer | Boolean | equality | |
| integer | integer | equality | |
| integer | string | equality | |
| string | Boolean | equality | |
| string | integer | equality | |
| string | string | equality | |
!=
| |||
| Boolean | Boolean | inequality | |
| Boolean | integer | inequality | |
| Boolean | string | inequality | |
| integer | Boolean | inequality | |
| integer | integer | inequality | |
| integer | string | inequality | |
| string | Boolean | inequality | |
| string | integer | inequality | |
| string | string | inequality | |
<
| |||
| Boolean | Boolean | invalid | |
| Boolean | integer | invalid | |
| Boolean | string | invalid | |
| integer | Boolean | invalid | |
| integer | integer | less than | |
| integer | string | invalid | |
| string | Boolean | invalid | |
| string | integer | invalid | |
| string | string | less than (lexicographic) | |
<=
| |||
| Boolean | Boolean | invalid | |
| Boolean | integer | invalid | |
| Boolean | string | invalid | |
| integer | Boolean | invalid | |
| integer | integer | less than or equal to | |
| integer | string | invalid | |
| string | Boolean | invalid | |
| string | integer | invalid | |
| string | string | less than or equal to (lexicographic) | |
>
| |||
| Boolean | Boolean | invalid | |
| Boolean | integer | invalid | |
| Boolean | string | invalid | |
| integer | Boolean | invalid | |
| integer | integer | greater than | |
| integer | string | invalid | |
| string | Boolean | invalid | |
| string | integer | invalid | |
| string | string | greater than (lexicographic) | |
>=
| |||
| Boolean | Boolean | invalid | |
| Boolean | integer | invalid | |
| Boolean | string | invalid | |
| integer | Boolean | invalid | |
| integer | integer | greater than or equal to | |
| integer | string | invalid | |
| string | Boolean | invalid | |
| string | integer | invalid | |
| string | string | greater than or equal to (lexicographic) |
Examples
Hello World
i just wanna tell you "Hello World"
FizzBuzz
we're no strangers to i
gotta make i 0
we've known i for 100
inside we both know i % 15 == 0 then
i just wanna tell you "FizzBuzz"
never gonna turn around i % 3 == 0 then
i just wanna tell you "Fizz"
never gonna turn around i % 5 == 0 then
i just wanna tell you "Buzz"
never gonna let you down
i just wanna tell you i
never gonna give you up
never gonna give you up
Truth-Machine
A truth-machine shall be demonstrated:
we're no strangers to yourInput gotta make yourInput your heart's been aching but you're too shy to say 'Please input 0 or 1' i just wanna tell you yourInput a full commitment's what I'm thinking of yourInput == 1 i just wanna tell you yourInput never gonna give you up
Looping Counter
This program counts from inclusive one (1) to inclusive 100, printing on each line a tally of asterisks (“*”) tantamount to the respective counter state:
we're no strangers to counter gotta make counter 1 we've known counter for 100 i just wanna tell you '*' * counter never gonna give you up
Cat Program
An infinitely repeating cat program is implemented as such:
a full commitment's what I'm thinking of True i just wanna tell you your heart's been aching but you're too shy to say 'Please input a character:' never gonna give you up
99 Bottles of Beer
The following program prints the lyrics of the song “99 Bottles of Beer”:
we're no strangers to number_of_bottles
gotta make number_of_bottles 99
a full commitment's what I'm thinking of number_of_bottles > 0
inside we both know number_of_bottles > 2 then
i just wanna tell you number_of_bottles + ' bottles of beer on the wall,'
i just wanna tell you number_of_bottles + ' bottles of beer.'
i just wanna tell you 'Take one down, pass it around,'
i just wanna tell you number_of_bottles - 1 + ' bottles of beer on the wall.'
i just wanna tell you
never gonna turn around number_of_bottles == 2 then
i just wanna tell you number_of_bottles + ' bottles of beer on the wall,'
i just wanna tell you number_of_bottles + ' bottles of beer.'
i just wanna tell you 'Take one down, pass it around,'
i just wanna tell you number_of_bottles - 1 + ' bottle of beer on the wall.'
i just wanna tell you
never gonna let you down
i just wanna tell you number_of_bottles + ' bottle of beer on the wall,'
i just wanna tell you number_of_bottles + ' bottle of beer.'
i just wanna tell you 'Take one down, pass it around,'
i just wanna tell you 'No bottles of beer on the wall.'
i just wanna tell you
never gonna give you up
gotta make number_of_bottles number_of_bottles - 1
never gonna give you up
Interpreter
- Common Lisp implementation of the NeverGonna programming language.
Computational class
It is easy to implement a 2 register minsky machine in NeverGonna, so it is Turing complete.