Rulz Programming Language

Rulz and Rulz Language is Copyright © G.A.Jennings, 2015-2023.

This is language specification 2-1/2; last updated 6 October 2022.

October 2023: This stuff is REALLY weird. Or maybe the Langauge is... Or the coder... Whatever, things they are um changing.

What Rulz Is

Rulz, pronounced "rules", is a general purpose computer language. The language is minimalist with no use of traditional braces, parentheses or commas. It includes all basic types, flow control, blocks, loops and subroutines.

Introduction

Though yet to be specified formally, Rulz has an assembly language-like structure and uses PHP-like variables and types, and borrows features from Bash and Perl.

But instead of "statements" and "expressions", there are "rules". A group of "rules" in a subroutine is called a "Rule" (uppercase "r"). Together, rules and Rules make up a Rulz Program.

Code Start

Update 20 Nov 2022: I have started to publish the code, but need to explain much about it...

Rulz, The Code

Quick Start

Here's a "normal" code thing:

if (EXPR) do();

Rulz just asks, what if if was ?:

? (EXPR) do();

Rulz also asks what if EXPR was first (storing the result in a special variable, and the ? is a test of that special variable):

(EXPR) ? do();

Which in "normalclature" could be:

$t = (EXPR); if ($t) do();

But where $t is "internal":

(EXPR) if do();

That is similar to Perl. Also in Perl and PHP are things like:

(EXPR) && do();

Rulz is just "reductive", finally eliminating the no longer necessary characters, (, ) and ;, though adding a newline:

EXPR
? do

So there is nothing really new here.

Features

References: • OperatorsVariablesData TypesSubroutines
Details: • LexerRegex Example

There is a "Tutorial" modeled after other, more typical programming documentation, Rulz Tutorial.

Naming Conventions

This document uses some identifiers here in particular ways.

rule                    Rulz language statement
Rule                    two or more rules together or a subroutine
var                     variable name (to be set)
val                     literal value (number, string, etc.)
$var                    variable
argument                literal or variable (arg)

Basic Syntax

The basic format of a rule is:

<operator|builtin|subroutine|label>[arguments]

Where:

operator                arithmetic, conditional, or other operator
builtin                 builtin command or standard function
subroutine              name of set of one or more rules; called a Rule
label                   a placeholder for the "jump" operator
arguments               zero or more arguments (literals, variables)

Though usually, Rulz uses a format like:

OP [ARGS]

Further describing that basic construct as a "RULE", as there are compound operators, those that can have another rule as an argument, are like:

OP OP [ARGS]

And that can be described like:

OP RULE

Left-handedness

Rulz' most unique syntax is that operators are always "first on the line" and there is only one per rule.

For example, assignment is =var argument and not var = argument. As in Bash, variable assignment does not include the $.

This is known as "prefix notation" for operations (expressions), but Rulz syntax is more "prefix statement notation".

Hello World

Here is the ubiquitous "Hello World" program in Rulz.

^Hello World

The ^ is the "print operator" which is like echo in Bash, outputting all arguments, separated by spaces, terminated with a newline. It also shows that, like Bash and Perl, barewords—identifiers of letters only—are treated as strings. To use any other characters quotes need to be used.

^"Hello, World!"

Otherwise the punctuation characters will be treated as separate arguments:

^Hello, World!           prints as 'Hello , World !'

White Space

Spaces are needed only in the case of ambiguity. (Though this is not a "free-form" language.) This uses a variable to print "Hello World".

=  name'Hello World'
^   $name

For clarity, most examples here use spaces (though it's kind of a convention to not use a space after the operator).

Comments

Rulz supports the three basic types of comments: single character beginning a comment line, single character introducing a trailing comment and a block comment defined by begin/end character pairs.

In Rulz, comments are operators (and are "removed" at run-time).

"While we usually think of quotes as literal values, in Perl they function as operators, providing various kinds of interpolating and pattern matching capabilities." – PerlOp

Oh... If at this point you're like, still here, peruse STEM. (I just saw it yesterday, January 26th, 2024).

Types

Rulz has the basics; boolean, string, list (array) and handle (stream). But, though maybe at times internally integers are used, at the high level the numerical type is number and will work like integers or floats depending on context.

There are constants for TRUE, FALSE and the PHP-like NULL (undef).

Rulz has several pseudo-types such as file, option and argument—which are similar to barewords but are more specialized in certain contexts.

Variables

Variables do not need to be declared. Accessing a non-assigned variable will result in a type's "false", "zero", "empty" or "null" value.

Basic variables are like $var where "var" is one or more lowercase letters, and, PHP-like, can be assigned any type. Variable assignment is Bash-like with the $ not used.

Like Bash and Perl all variables are global and there are "my" and "local" attributes for subroutines.

There are Perl-like "special variables" of the format: $[0-9[:punct:]]. The special variables $0 and $_, differ from their Perl counterparts and are used as defaults for most Operators and Builtins.

The variable $0 is called the "return value", or "r-value",and contains the result of function calls and is the default for most operators and commands.

The variable $_ is called the "function value", or "f-value", and is the default argument for some operators and functions.

Operators

Comments

# a single character comment line; can also # trail a rule
## start of a block comment that will end at the next ##

The block comment usually is for multiple lines.

Conditional Operators

There are two conditional operators. In their simplest for they test the $0 special variable.

? rule                  run rule if previous rule was true
! rule                  run rule if previous rule was false

The logical operations are actually "true if true" and "true if false".

The conditional operators can test a specific variable:

? $var rule             run rule if $var true
! $var rule             run rule if $var false

Those two rules are the reduction of the syntax of these two PHP statements.

if ($var) statement;
if (!$var) statement;

The conditional operators have "compound forms".

<?!> [operator [$var]] rule

See #Compound Conditionals.

And there are ternary versions based on a variable.

? $var rule rule
! $var rule rule

And for result of a rule.

? rule rule rule
! rule rule rule

(Though those are not a "ternary assignment operator" as in other languages.)

Rulz' boolean type is PHP/Perl-like. The conditional operators are "kinda-loose", with 0, "" (empty string) and () (empty list) evaluating false, and all other values evaluating true.

There is another case that defaults to true, "0" (ASCII 48), but as will be seen, there are ways to change run-time operations in ways similar to Bash and Perl – there is a "special variable" to change that to be false.

Assignment Operator

The assignment operator has the format:

= [var] [argument]      assignment

An assignment operator all by itself is valid: it "resets" the special variable $0 to a "false" value. Otherwise it will set a variable to a value.

= var 1729

Note that = var does not effect $var but assigns the string var to $0.

There are "compound" versions for multiple variables.

= a,b,c 1,2,foo

Without values, compound variables are set to it's "zero" value.

= i,j

With just one value the variables are all set to it. This is same as above.

= i,j 0

To set some and default some, use a comma.

= i,j 1,

Un-Assignment Operator

!= var [vars]           unset $var and all following variables

Arithmetic Operators

The arithmetic operators – which are similar to assignment and so are "prefix modified" assignment operators – have three forms:

OP argument
OP var argument
OP var argument argument

With just one argument:

+= argument             add to $0
-= argument             subtract from $0
*= argument             multiply $0 by
/= argument             divide $0 by
%= argument             modulo $0 of
.= argument             concatenate $0 with

The concatenation operator appends a string to string (PHP-like); and there will be some "type juggling" here with mixed types. See [rulztypes].

And to apply to a variable:

+= var argument         add to $var
-= var argument         subtract from $var
*= var argument         multiply $var by
/= var argument         divide $var by
%= var argument         modulo $var of
.= var argument         concatenate $var with

When used with a variable name and two arguments the result is like other language arithmetic.

+= var arg arg          $var = arg + arg
-= var arg arg          $var = arg - arg
*= var arg arg          $var = arg * arg
/= var arg arg          $var = arg / arg
%= var arg arg          $var = arg % arg
.= var arg arg          $var = arg . arg

See also #List Assignment Operations.

The exponentiation operator in Rulz is actually a mathematical operator. See #Mathematical Operators.

Increment Decrement Operators

As increment and decrement operators in most languages are just a syntactical shortcut, Rulz simply has one more version of add and subtract.

+=                      increment $0
-=                      decrement $0
+= var                  increment $var
-= var                  decrement $var

(So, there actually are no increment and decrement operators. Only addition and subtraction, for that's all increment and decrement are.)

Constant Assignment Operators

There are two ways to create constants—one for enumerations and one for values.

,= A B C                A = 1; B = 2; C = 3
:= A 1 B 2 C 3          same

The latter can also have extra spaces.

:= A 1  B 2  C 3        same

Or it can have none.

:=A1B2C3                same

Admitedly those are kind of kludgey (looking) so there are ways of defining constants that are more better. See [rulzdata.html].

Bitwise Operators

These operators are listed by number of arguments.

The unary not of bits takes zero or one arguments. If none, $0 is a not of itself, else it is not of the variable.

~= [var]                result is Not of bits

The xor and shift operators take one or two arguments, with the result in $0 or a variable respectively.

^= argument [argument]  result is Xor of bits
<= argument [argument]  result is bit shift left
>= argument [argument]  result is bit shift right

The and and or operators can take from one to many arguments.

&= argument [arguments] result is And of bits
|= argument [arguments] result is Or of bits

With one or two values, the result is in $0 (with one value the result is the binary operation with $0 (itself) as the first operand).

Examples

&= 1                    $0 is $0 And 1
&= $a $b                $0 is $a And $b

With a variable name the operations are the same:

&= a 1                  $a is $0 And 1
&= c $a $b              $c is $a And $b

With three or more arguments, the result is the operator applied to all values.

|= 1 2 4 8              $0 is 15
|= var 1 2 4 8          $var is 15

Logical Operators

The logical operators set $0 with the result of the operation.

!! [argument]           true if argument or $_ not true
|| [arguments]          true if any argument or $_ true
&& [arguments]          true if all arguments or $_ true
^^ argument [argument]  true if either argument or argument and $_ true but not both

In addition, there are two named operators that operate a little different.

or arguments            result is the first argument that is found true
and arguments           result is the first argument if all are true

And two that are unique to Rulz.

is argument [argument]  true if argument or argument and $_ are of the same type
not argument [argument] true if argument or argument and $_ are not of the same type

Comparison Operators

Comparison operators are "modified" conditional operators, the result in $0, and take one or two arguments. If one, the comparison is against $_; if two, the comparison is between the first and second arguments.

=? argument [argument]  true if equal
=! argument [argument]  true if not equal
<? argument [argument]  true if less than
<! argument [argument]  true if not less than
>? argument [argument]  true if greater than
>! argument [argument]  true if not greater than

See also #Compound Conditionals.

List Comparison Operators

=? list [list]          true if have same key/value pairs
=! list [list]          true if not the same

List Assignment Operations

The #Assignment Operators can be used with lists.

+= list value           add value to each list element
+= list list            add each element of second to each element of first

All basic arithmetic operations are similarly supported.

Concatenation is either push (append) or merge.

.= list value           push value onto list
.= list list            merge second list into first list

There are also several operators dedicated to lists.

List Bitwise Operations

Bitwise operations also can be applied to lists in a unique way—with just one argument $_ will be used as if it were the second.

&= [list] list          union
|= [list] list          replace
^= [list] list          unique
~= [list] list          intersect
<= [var] list           shift
>= [var|val] list       unshift

See also #List Operators.

Defined Operators

The defined operators mimic the PHP isset and the Perl defined functions.

?? var                  isset (defined)
?! var                  not isset (not defined)
&? var                  defined [subroutine]
&! var                  not defined [subroutine]

Where var is a variable name or interpolates to a variable name.

Evaluation Operator

The evaluation operator mimics the PHP and Perl eval functions.

`= var                  eval string or list of strings

The list version is similar to calling a subroutine though no arguments are involved.

Percent Operators

The percent operators are function-like.

=% argument [argument]  percentage of
/% argument [argument]  percentage against
+% argument [argument]  percentage add
-% argument [argument]  percentage from
*% argument [argument]  percentage between

Mathematical Operators

The Mathematical operators are function-like.

v/ argument             square root
2/ argument             square
1/ argument             reciprocal
a/ argument             absolute
^/ argument             exponent

They work like #String Operators defined below. (There are many more.)

File Operators

The file I/O operators mimic basic file functions. The $0 variable is TRUE on success or FALSE on error.

&  [fh] file            open file for reading, handle in $_ or $fh
-& [fh] file            open file for writing, handle in $_ or $fh
+& [fh] file            open file for appending, handle in $_ or $fh

The file read operators returns the number of bytes read or FALSE on error.

<& [$fh] var            read line from $fh or $_ to $var
<& [$fh] var number     read number bytes from $fh or $_ to $var
[& [$fh] var            read line from $fh or $_ to $var without EOL
{& [$fh] var            read character from $fh or $_ to $var
(& [$fh] var format     parse line from $fh or $_ to $var according to format 
/& [$fh] var pattern    parse line from $fh or $_ to $var according to regular expression

The file write operators returns the number of bytes written or FALSE on error.

>& [$fh] $var           write $var to $fh or $_ with EOL
]& [$fh] $var           write $var to $fh or $_ without EOL
}& [$fh] $var           write character $var to $fh or $_
)& [$fh] var format     write $var to $fh or $_ according to format

Other file operators.

@& [$fh]                eof test
.& [$fh]                close
%& [$fh]                stat
=& [$fh] number         seek
,& [$fh]                rewind
?& [$fh]                tell
:+ [$fh]                truncate

With some file name versions.

%& file                 stat
^& file                 touch
!& file                 delete
|& file file            rename/move

The use of $_ as a default for the file handle is odd as many other operators can subsequently and inadvertently overwrite $_. Using $_ is recommended only for short sequences of code.

See also #Test Operators.

There are several function-like operators that read or write files directly.

<< [var] file           get file as string into $_ or $var
[< [var] file           get file as list into $_ or $var with EOL
(< [var] file           get file as list into $_ or $var without EOL
>> [$var] file          put $var or $_ as string to file
]> [$var] file          put $var or $_ as list to file with EOL
)> [$var] file          put $var or $_ as list to file without EOL
+> [$var] file          append $var or $_ as string to file
-> [$var] file          prepend $var or $_ as string to file

Special variable $0 is set to FALSE for error, TRUE for success; except that read operators return the number of bytes read, and write operators return the numbers of bytes written on success.

The put, append and prepend file operators have a dual role with two arguments in that if the first argument is the name of a file that exists the file's contents will be used in place of the variable contents.

>> filea fileb          copy file
+> filea fileb          append file
-> filea fileb          prepend file

Finally, a file can be read and output directly to "standard out".

~< file                 output file (readfile)

Load Rules Operator

A Rule file can be included.

.< file                 load source file

The file being included will not be run and any rules outside of subroutines will be ignored. What this means is that only subroutines will be loaded. See [rulzsub.html].

Rulz subroutines can be redefined—any existing subroutine of the same name will be replaced.

There are Rulz builtins for running Rulz programs. See [builtins].

Execution Operator

The execution operator, returning the program's output, comes in two forms. The first sets $0 and exec's all arguments as a single string.

`` whoami --version

And the other is as a "backtick argument" that is operator like for assigning to a variable.

= var `whoami --version`

See [rulzargs].

Search Replace Operator

The regular expression operator is like a "search or search and replace" operator, and it too has two forms. The "search" (match):

// /pattern/            search $_ for pattern
// $var /pattern/       search $var for pattern

And the "search replace":

// /pattern/text/       search $_ and replace with text
// var /pattern/text/   search $var and replace with text

As with variable assignment, the variable name for replace is without the $.

After a successful match, the following special variables are set:

$#                      number of matches
$&                      the string that matched
$1                      the first subexpression match; $2 the 2nd, etc.

For search, $0 is set to the number of matches; for replace, the number of replacements.

These are full PCRE strings except that there is no multi-line version and their arguments can only use / as delimiters.

Translate Operator

The translate operator is like PHP's strtr and Perl's tr///.

\\ /searchlist/replacelist/
\\ var /searchlist/replacelist/

Jump Operator

The jump operator is .. It can have a number of rules to jump over or a string for a "label" to jump to.

. 3                     jump 3 rules
. label                 jump to label

A label is operator-like.

:label                  define label

Multiple labels of the same name is not an error; the jump to label will just go to the first label it finds. Labels by themselves are a "No Op".

Variables can be used for jump conditions:

= n 3                   assign $n
. $n                    jump $n lines
= b label               assign $b
. $b                    jump to label $b

A jump operator can be preceded by a conditional operator:

? . label               conditional jump to label

Though such compound operators are unique to conditional/comparison operators not the jump operator.

Loop Operators

@do                     while 1
<rules>
@end
@each [$var]            foreach on $0 or $var (as keys and values)
<rules>
@end
@for [$var]             foreach on $0 or $var (as values)
<rules>
@end
@until [$var|rule]      while $0 or [$var|rule] is false
<rules>
@end
@while [$var|rule]      while $0 or [$var|rule] is true
<rules>
@end

With @for the special variable $_ is set to the array value. With @each the special variable $( is set to the key, and $) the value.

These operators cannot be nested.

The following operators can control the loop:

.. [rule]               break
>. [rule]               next (continue)
<. [rule]               redo

The @until and @while operators have one line versions.

@while <$var|rule> <rule>

With the caveat that for a conditional <rule> the loop condition is $0, which means that the loop will continue or not based on either <rule> setting $0 at some point.

When the loop conditional is a variable, the <rule> argument has to set the variable to continue or stop the loop, either through a subroutine or a builtin.

If Else Operators

These are not blocks in the sense of PHP or Perl; but are similar.

@if [$var|rule]          if $0 or $var or rule is true
<rules>
[@else]
[rules]
@end

These operators cannot nest.

Not being able to nest loops/blocks is a minor thing as there are subroutines.

Loop Operator Aliases

There are, of course, "short form" loop operators. (Though, actually, the "long form" are the aliases.)

c@                      @case
d@                      @do
e@                      @each
f@                      @for
i@                      @if
s@                      @switch
u@                      @until
w@                      @while
@                       @end

Break Return Exit

A modifed jump is an exit depending on context:

..                      break, return, exit

In a loop it does a "break", in a subroutine a "return" and in Top Rules "exit".

Related operators are:

>.                      continue (next)
<.                      redo

And kinda related, and Perl-like:

^.                      die

Test Operators

Test Operators, based on Bash conditional operators, set $0 with the result of a test on a file—TRUE or FALSE. If the test argument is missing $_ will be used.

f- [file]               file exists
d- [file]               file exists and is a directory
r- [file]               file is readable
w- [file]               file is writable

The following "tests" will return a value other than TRUE for success.

s- [file]               file size
p- [file]               file permissions
t- [file]               file type
g- [file]               file group
a- [file]               file access time
c- [file]               file change time
m- [file]               file modification time

The type test operators test the type of it's argument or $_.

S- [argument]           is string
I- [argument]           is integer
D- [argument]           is double
A- [argument]           is list or hash
N- [argument]           is numeric
B- [argument]           is boolean
U- [argument]           is null
T- [argument]           is true (PHP like)
Z- [argument]           is empty (PHP like)

These return a value other than TRUE.

L- [argument]           integer length if string or count if list
Y- [argument]           string indicating type (PHP like)

Type Operators

Type operators are extensions to test operators on types, and are similar to POSIX character classes and PHP ctype functions.

Again, $_ is used if no argument and the boolean result is in $0.

u? [argument]           is uppercase
l? [argument]           is lowercase
d? [argument]           is decimal
s? [argument]           is whitespace 
w? [argument]           is word character
n? [argument]           is alpha numeric
a? [argument]           is alpha
c? [argument]           is control
g? [argument]           is graph
p? [argument]           is printable
v? [argument]           is punctuation
x? [argument]           is hexadecimal

All have an ! version to negate the test.

String Operators

The string operators perform function-like operations on strings.

u~ [count] [arg]        to upper case
l~ [count] [arg]        ro lower case
n~ [arg]                length
q~ [arg]                quote meta 
i~ offset [len] [arg]   index (substr)
s~ string [off] [arg]   string occurrence
S~ string [off] [arg]   string occurrence (case insensitive)
p~ string [off] [arg]   string position
P~ string [off] [arg]   string position (case insensitive)
c~ [arg]                chop (PHP like)
C~ [arg]                chomp (Perl like)
t~ [string] [arg]       trim
T~ [string] [arg]       trim right
L~ [string] [arg]       trim left
f~ format arg [args]    sprintf
F~ format arg [args]    sscanf
h~ [arg]                htmlentities
H~ [arg]                htmlspecialchars
x~ [string] [arg]       explode
w~ [len] [string] [arg] wordwrap
r~ string string [arg]  string replace
R~ string string [arg]  string replace (case insensitive)
e~ [arg]                urlencode
E~ [arg]                urldecode
y~ [string] [arg]       crypt
g~ string [arg]         preg split
b~ [string] [arg]       basename
d~ [arg]                dirname

List Operators

List operators perform Perl/PHP functions. Most create (or modify) lists.

/[ [var] string [string] split
:[ [var] list [string]  join
~[ [var] list           values
%[ [var] list           keys
@[ [var] list           sort
\[ [var] list           reverse
<[ [var] list           shift
>[ [var] list           unshift
-[ [var] list           pop
+[ [var] list           push
,[ [var] list off [len] slice
([ [var] list string    extract
^[ [var] list list      difference

Without var the results are in $_. For @[ and [ list can be a reference to a list.

List Arithmetic Operators

+[ list list            sum
-[ list list            subtract
*[ list list            product
/[ list list            division

Operators that act upon a list or a hash.

#[ [var] <list|hash>    count
=[ [var] <list|hash>    index/key exists (boolean)
?[ [var] <list|hash>    value exists (boolean)
[[ [var] <list|hash>    value exists (search) returns key
*[ [var] <list|hash>    random value

See also #List Assignment Operations, #List Bitwise Operations and #List Interpolation.

List Operator Aliases

j[                      join
v[                      values
k[                      keys
s[                      sort
r[                      reverse
p[                      pop
P[                      push
l[                      split
L[                      slice
d[                      difference
i[                      index/key exists
e[                      value exists (boolean)
E[                      value exists (search)                       ; ]

Call Psuedo-Operator

An & character preceding an argument is another "operator argument" for using a builtin or subroutine return value as an argument.

This Rule calls time with the return in $0 which is passed to date.

time
date "M d, Y" $0

The & argument turns functions into arguments.

date "M d, Y" &time

Otherwise, time would be seen as a bareword.

See [rulzargs].

Heredoc

"Here documents" are supported, with slightly unique syntax, which is that they are "begin/end operators"—a heredoc begins with a (( and ends on another (( on a line by itself (leading and trailing whitespace ignored).

<(
Here, here documents are multi-line print statements.
They include interpolation and escapes (\$foo = $foo).

These end on the next "<(" seen that starts at the first 
character. Leading whitespaces of "<(" are part of the 
string:
        <(

Lines are concatenated with spaces; blank lines are 
replaced by a newline.

  * Leading whitespace is preserved...

...the trailing newline is not. For that, end with one:

<(
<( var
This heredoc is assigned to a variable.
<(

A "nowdoc" is by the operator ((.

((
A "nowdoc" does not interpolate $vars and does not convert 
escapes like \\ or even \'. (Which is kind of Perl-like. I think.)
((

These operators introduce a kind of "operator attribute", in that appending a \n (the string literal, not a real newline) will modify it to append a newline to each line.

(( \n
1) Line 1.
2) Line 2.
3) Line 3.
((

If a heredoc (or theredoc described next) is last in a program or subroutine the ending operator is not required.

Theredoc

An extension to heredoc is to output text to a file—a "there document". This uses the operator >) and a file name.

=title "Rulz Programming Language"

>) head.htm
<!DOCTYPE html>
<html>
<head>
<title>$title</title>
</head>
>)

All the aspects of heredoc applies. The "now theredoc" is )).

Compound Conditionals

The #Conditional Operators can test some operators—basically combining two rules in one.

? <rule> <rule>
! f- .. ^$_ not found
! f- $f .. ^$f not found
! &error.log .. ^could not open log file

Similar to basing the conditional test on a variable, here, the conditional test is a rule and only those with operators that set $0 will work as expected.

! += v ^foo

That rule will always increment $v but will only print foo if $0 "is false".

! += ^foo

That rule will always increment $0 but will only print foo if $0 "was false".

Even though a builtin might set $0, they will not work this way:

? builtin $v ^foo

The ^foo will get passed to the builtin (as two arguments), which will be called is $0 true. This is where the comma pseudo-operator comes in.

? builtin $v , ^foo

So, ^foo will run based on the return of builtin $v.

Whitespace

Leading and trailing spaces and tabs are ignored. Operators and arguments can be separated by spaces or tabs.

? func
= foo 10
! += $foo
>? 10
= f ~/*

The latter rule's argument is a file glob; see [rulzargs].

If there is no ambiguity between operator and argument(s) spaces are not required at all.

?func
=foo10
!+=$foo
>?10
=f<~/*>
They hurt you at home and they hit you at school.
They hate you if you're clever and they despise a fool.
'Til you're so fucking crazy you can't follow their rules.
  - John Lennon