Number of keywords by language
15
true
false
nil
when
and
or
not
in
fn
do
end
catch
rescue
after
else
15
as
assert
case
const
echo
fn
if
import
let
opaque
panic
pub
todo
type
use
19
if
else
repeat
while
function
for
in
next
break
TRUE
FALSE
NULL
Inf
NaN
NA
NA_integer_
NA_real_
NA_complex_
NA_character_
20
break
case
catch
classdef
continue
else
elseif
end
for
function
global
if
otherwise
parfor
persistent
return
spmd
switch
try
while
23
and
break
do
else
elseif
end
false
for
function
global
goto
if
in
local
nil
not
or
repeat
return
then
true
until
while
25
break
default
func
interface
select
case
defer
go
map
struct
chan
else
goto
package
switch
const
fallthrough
if
range
type
continue
for
import
return
var
27
after
and
andalso
band
begin
bnot
bor
bsl
bsr
bxor
case
catch
div
else
end
fun
if
maybe
not
of
or
orelse
receive
rem
try
when
xor
35
if
elif
else
for
while
match
when
break
continue
pass
return
class
class_name
extends
is
in
as
self
super
signal
func
static
const
enum
var
breakpoint
preload
await
yield
assert
void
PI
TAU
INF
NAN
37
await
break
case
catch
class
const
continue
debugger
default
delete
do
else
export
extends
false
finally
for
function
if
import
in
instanceof
new
null
return
super
switch
this
throw
true
try
typeof
var
void
while
with
yield
38
False
await
else
import
pass
None
break
except
in
raise
True
class
finally
is
return
and
continue
for
lambda
try
as
def
from
nonlocal
while
assert
del
global
not
with
async
elif
if
or
yield
match
case
type
40
__DATA__
__END__
__FILE__
__LINE__
__PACKAGE__
and
foreach
cmp
continue
CORE
do
else
elsif
eq
exp
for
ge
gt
if
le
lock
lt
ne
no
or
package
q
qq
qw
qx
m
s
sub
tr
until
while
xor
y
qr
unless
41
__ENCODING__
__LINE__
__FILE__
BEGIN
END
alias
and
begin
break
case
class
def
defined?
do
else
elsif
end
ensure
false
for
if
in
module
next
nil
not
or
redo
rescue
retry
return
self
super
then
true
undef
unless
until
when
while
yield
43
as
async
await
break
const
continue
crate
dyn
else
enum
extern
false
fn
for
if
impl
in
let
loop
match
mod
move
mut
pub
ref
return
self
Self
static
struct
super
trait
true
type
unsafe
use
where
while
'static
macro_rules
raw
safe
union
43
As
Binary
ByRef
ByVal
Date
Else
Empty
Error
False
For
Friend
Get
Input
Is
Len
Let
Lock
Me
Mid
New
Next
Nothing
Null
On
Option
Optional
ParamArray
Print
Private
Property
PtrSafe
Public
Resume
Seek
Set
Static
Step
String
Then
Time
To
True
WithEvents
46
addrspace
align
allowzero
and
anyframe
anytype
asm
break
callconv
catch
comptime
const
continue
defer
else
enum
errdefer
error
export
extern
fn
for
if
inline
linksection
noalias
noinline
nosuspend
opaque
or
orelse
packed
pub
resume
return
struct
suspend
switch
test
threadlocal
try
union
unreachable
var
volatile
while
56
abstract
case
catch
class
def
do
else
enum
export
extends
false
final
finally
for
given
if
implicit
import
lazy
match
new
null
object
override
package
private
protected
return
sealed
super
then
throw
trait
true
try
type
val
var
while
with
yield
as
consume
derives
end
erased
extension
infix
inline
opaque
open
throws
tracked
transparent
update
using
56
and
as
assert
asr
begin
class
constraint
do
done
downto
else
end
exception
external
false
for
fun
function
functor
if
in
include
inherit
initializer
land
lazy
let
lor
lsl
lsr
lxor
match
method
mod
module
mutable
new
nonrec
object
of
open
or
private
rec
sig
struct
then
to
true
try
type
val
virtual
when
while
with
57
abstract
as
assert
boolean
break
byte
case
catch
char
class
const
continue
def
default
do
double
else
enum
extends
false
final
finally
float
for
goto
if
implements
import
in
instanceof
int
interface
long
native
new
null
package
private
protected
public
return
short
static
strictfp
super
switch
synchronized
this
threadsafe
throw
throws
transient
true
try
void
volatile
while
59
auto
break
case
char
const
continue
default
do
double
else
enum
extern
float
for
goto
if
int
long
register
return
short
signed
sizeof
static
struct
switch
typedef
union
unsigned
void
volatile
while
inline (C99)
restrict (C99)
_Bool (C99)(deprecated in C23)
_Imaginary (C99)
_Complex (C99)
_Generic (C11)
_Noreturn (C11)(deprecated in C23)
_Static_assert (C11)(deprecated in C23)
_Thread_local (C11)(deprecated in C23)
_Alignas (C11)(deprecated in C23)
_Alignof (C11)(deprecated in C23)
_Atomic (C11)
alignas (C23)
alignof (C23)
bool (C23)
constexpr (C23)
false (C23)
nullptr (C23)
static_assert (C23)
thread_local (C23)
true (C23)
typeof (C23)
typeof_unqual (C23)
_BitInt (C23)
_Decimal128 (C23)
_Decimal32 (C23)
_Decimal64 (C23)
64
abstract
continue
for
new
switch
assert
default
if
package
synchronized
boolean
do
private
this
break
double
implements
protected
throw
byte
else
import
public
throws
case
enum
instanceof
return
transient
catch
extends
int
short
try
char
final
interface
static
void
class
finally
long
volatile
float
native
super
while
exports
opens
requires
uses
yield
module
permits
sealed
var
non-sealed
provides
to
when
open
record
transitive
with
65
and
array
as
asm
begin
case
class
const
constructor
destructor
dispinterface
div
do
downto
else
end
except
exports
file
finalization
finally
for
function
goto
if
implementation
in
inherited
initialization
inline
interface
is
label
library
mod
nil
not
object
of
or
out
packed
procedure
program
property
raise
record
repeat
resourcestring
set
shl
shr
string
then
threadvar
to
try
type
unit
until
uses
var
while
with
xor
69
abstract
as
assert
async
await
base
break
case
catch
class
const
continue
covariant
default
deferred
do
dynamic
else
enum
export
extends
extension
external
factory
false
final (var)
final (class)
finally
for
Function
get
hide
if
implements
import
in
interface
is
late
library
mixin
new
null
of
on
operator
part
required
rethrow
return
sealed
set
show
static
super
switch
sync
this
throw
true
try
type
typedef
var
void
when
with
while
yield
72
__halt_compiler()
abstract
and
array()
as
break
callable
case
catch
class
clone
const
continue
declare
default
die()
do
echo
else
elseif
empty()
enddeclare
endfor
endforeach
endif
endswitch
endwhile
eval()
exit()
extends
final
finally
for
foreach
function
global
goto
if
implements
include
include_once
instanceof
insteadof
interface
isset()
list()
namespace
new
or
print
private
protected
public
require
require_once
return
static
switch
throw
trait
try
unset()
use
var
while
xor
yield
yield
from
fn (as of PHP 7.4)
match (as of PHP 8.0)
readonly (as of PHP 8.1.0)
74
abort
abs
abstract (Ada 95)
accept
access
aliased (Ada 95)
all
and
array
at
begin
body
case
constant
declare
delay
delta
digits
do
else
elsif
end
entry
exception
exit
for
function
generic
goto
if
in
interface (Ada 2005)
is
limited
loop
mod
new
not
null
of
or
others
out
overriding (Ada 2005)
package
parallel (Ada 2022)
pragma
private
procedure
protected (Ada 95)
raise
range
record
rem
renames
requeue (Ada 95)
return
reverse
select
separate
some (Ada 2012)
subtype
synchronized (Ada 2005)
tagged (Ada 95)
task
terminate
then
type
until (Ada 95)
use
when
while
with
xor
74
abstract
and
let
as
assert
base
begin
class
default
delegate
do
done
downcast
downto
elif
else
end
exception
extern
false
finally
fixed
for
fun
function
global
if
in
inherit
inline
interface
internal
lazy
let
let!
match
match!
member
module
mutable
namespace
new
not
null
of
open
or
override
private
public
rec
return
return!
select
static
struct
then
to
true
try
type
upcast
use
use!
let!
Dispose
val
void
when
while
with
yield
yield!
const
79
as
as?
break
class
continue
do
else
false
for
fun
if
in
!in
interface
is
!is
null
object
package
return
super
this
throw
true
try
typealias
typeof
val
var
when
while
by
catch
constructor
delegate
dynamic
field
file
finally
get
import
init
param
property
receiver
set
setparam
value
class
where
abstract
actual
annotation
companion
const
crossinline
data
enum
expect
external
final
infix
inline
inner
internal
lateinit
noinline
open
operator
out
override
private
protected
public
reified
sealed
suspend
tailrec
vararg
84
abstract
accessor
any
as
asserts
assert
bigint
boolean
break
case
catch
class
continue
const
constructor
debugger
declare
default
defer
delete
do
else
enum
export
extends
false
finally
for
from
function
get
if
implements
import
in
infer
instanceof
interface
intrinsic
is
keyof
let
module
namespace
never
new
null
number
object
package
private
protected
public
override
out
readonly
require
global
return
satisfies
set
static
string
super
switch
symbol
this
throw
true
try
type
typeof
undefined
unique
unknown
using
var
void
while
with
yield
async
await
of
98
and
and_eq
asm
atomic_cancel (TM TS)
atomic_commit (TM TS)
atomic_noexcept (TM TS)
auto (1) (3) (4) (5)
bitand
bitor
bool
break
case
catch
char
class (1)
compl
const
const_cast
continue
default (1)
delete (1)
do
double
dynamic_cast
else
enum (1)
explicit
export (1) (4)
extern (1)
false
float
for (1)
friend
goto
if (3) (5)
inline (1) (3)
int (1)
long
mutable (1)
namespace
new
not
not_eq
operator (1)
or
or_eq
private (4)
protected
public
reflexpr (reflection TS)
register (3)
reinterpret_cast
return
short
signed
sizeof (1)
static
static_cast
struct (1)
switch
synchronized (TM TS)
template
this (5)
throw (3) (4)
true
try
typedef
typeid
typename (3) (4)
union
unsigned
using (1) (4)
virtual
void
volatile
wchar_t
while
xor
xor_eq
alignas (C++11)
alignof (C++11)
char16_t (C++11)
char32_t (C++11)
constexpr (C++11) (3)
decltype (C++11) (2)
noexcept (C++11)
nullptr (C++11)
static_assert (C++11)
thread_local (C++11)
char8_t (C++20)
concept (C++20)
consteval (C++20) (5)
constinit (C++20)
co_await (C++20)
co_return (C++20)
co_yield (C++20)
requires (C++20)
contract_assert (C++26)
102
associatedtype
borrowing
class
consuming
deinit
enum
extension
fileprivate
func
import
init
inout
internal
let
nonisolated
open
operator
precedencegroup
private
protocol
public
rethrows
static
struct
subscript
typealias
var
break
case
catch
continue
default
defer
do
else
fallthrough
for
guard
if
in
repeat
return
switch
throw
where
while
Any
as
await
catch
false
is
nil
rethrows
self
Self
super
throw
throws
true
try
#available
#colorLiteral
#else
#elseif
#endif
#fileLiteral
#if
#imageLiteral
#keyPath
#selector
#sourceLocation
#unavailable
associativity
async
convenience
didSet
dynamic
final
get
indirect
infix
lazy
left
mutating
none
nonmutating
optional
override
package
postfix
precedence
prefix
Protocol
required
right
set
some
Type
unowned
weak
willSet
106
assign
backspace
block data
call
close
common
continue
data
dimension
do
else
else if
end
endfile
endif
entry
equivalence
external
format
function
goto
if
implicit
inquire
intrinsic
open
parameter
pause
print
program
read
return
rewind
rewrite
save
stop
subroutine
then
write
allocatable
allocate
case
contains
cycle
deallocate
elsewhere
exit?
include
interface
intent
module
namelist
nullify
only
operator
optional
pointer
private
procedure
public
recursive
result
select
sequence
target
use
while
where
elemental
forall
pure
abstract
associate
asynchronous
bind
class
deferred
enum
enumerator
extends
final
flush
generic
import (in interfaces)
non_overridable
nopass
pass
protected
value
volatile
wait
block
codimension
do concurrent
contiguous
critical
error stop
submodule
sync all
sync images
sync memory
lock
unlock
impure
select rank
non_recursive
135
abstract
as
base
bool
break
byte
case
catch
char
checked
class
const
continue
decimal
default
delegate
do
double
else
enum
event
explicit
extern
false
finally
fixed
float
for
foreach
goto
if
implicit
in
int
interface
internal
is
lock
long
namespace
new
null
object
operator
out
override
params
private
protected
public
readonly
ref
return
sbyte
sealed
short
sizeof
stackalloc
static
string
struct
switch
this
throw
true
try
typeof
uint
ulong
unchecked
unsafe
ushort
using
virtual
void
volatile
while
add
allows
alias
and
ascending
args
async
await
by
descending
dynamic
equals
extension
field
file
from
get
global
group
init
into
join
let
managed (function pointer calling convention)
nameof
nint
not
notnull
nuint
on
or
orderby
partial (type)
partial (member)
record
remove
required
scoped
select
set
unmanaged
(function
pointer
calling
convention)
unmanaged
(generic
type
constraint)
value
var
when (filter condition)
where
(generic type constraint)
where
(query clause)
with
yield
170
AddHandler
AddressOf
Alias
And
AndAlso
As
Boolean
ByRef
Byte
ByVal
Call
Case
Catch
CBool
CByte
CChar
CDate
CDbl
CDec
Char
CInt
Class Constraint
Class Statement
CLng
CObj
Const
Continue
CSByte
CShort
CSng
CStr
CType
CUInt
CULng
CUShort
Date
Decimal
Declare
Default
Delegate
Dim
DirectCast
Do
Double
Each
Else
ElseIf
End Statement
End <keyword>
EndIf
Enum
Erase
Error
Event
Exit
False
Finally
For (in For…Next)
For Each…Next
Friend
Function
Get
GetType
GetXMLNamespace
Global
GoSub
GoTo
Handles
If
If()
Implements
Implements Statement
Imports (.NET Namespace and Type)
Imports (XML Namespace)
In
In (Generic Modifier)
Inherits
Integer
Interface
Is
IsNot
Let
Lib
Like
Long
Loop
Me
Mod
Module
Module Statement
MustInherit
MustOverride
MyBase
MyClass
NameOf
Namespace
Narrowing
New Constraint
New Operator
Next
Next (in Resume)
Not
Nothing
NotInheritable
NotOverridable
Object
Of
On
Operator
Option
Optional
Or
OrElse
Out (Generic Modifier)
Overloads
Overridable
Overrides
ParamArray
Partial
Private
Property
Protected
Public
RaiseEvent
ReadOnly
ReDim
REM
RemoveHandler
Resume
Return
SByte
Select
Set
Shadows
Shared
Short
Single
Static
Step
Stop
String
Structure Constraint
Structure Statement
Sub
SyncLock
Then
Throw
To
True
Try
TryCast
TypeOf…Is
UInteger
ULong
UShort
Using
Variant
Wend
When
While
Widening
With
WithEvents
WriteOnly
Xor
#Const
#Else
#ElseIf
#End
#If
Methodology and caveats (pedants click here)
Languages from https://survey.stackoverflow.co/2025/technology#most-popular-technologies-language-language but omitted some:
- Cool but not general purpose programming languages, yes maybe you can torture it into turing complete whatever but you know what I mean: HTML/CSS, SQL, Bash/Shell, PowerShell, Assembly
- Marked as duplicate: MicroPython
- Not sure which variant: Lisp
- Lower popularity than Gleam: Prolog, COBOL, Mojo
Don't read too much into this, for one thing not even sure how accurate it is, I might have made mistakes and for instance python has an "and" keyword that other languages don't, GDScript has PI and TAU keywords, imo these do not increase the complexity of the lanugage. And languages treat keywords a bit differently so it's not really apples to apples. Num keywords does not exactly represent language complexity. So this is pretty much just ragebait but at least the graph is pretty.
But again this is not necessarily meaningful. For example people say "oh Gleam has 15 keywords" which is probably true in some important technical sense or compiler definition, but doesn't count underscore which maybe isn't exactly a keyword in that technical sense, but practically speaking you need to know what underscore means to read Gleam case statements. Or for perl I only included the "Perl syntax" keywords, but if you included every word on that page it'd dwarf even VB .NET. Reducing the language to a single number of keywords might look like an objective measure, but elides the subjective consideration of what "feels" like a keyword when writing the language. To say nothing of C++ 11 vs 23 or whatever.
I omitted keywords that are reserved for future use but don't do anything, because a) makes Gleam look better and b) when you read code in a language you don't need to know anything about keywords that don't do anything. I also didn't count operators like "==", "+", "||", etc. Point is this is not really precise, imo when we talk about keywords we mean words, but my judgement is kind of made up.
If you think I messed up, I probably did, but out of incompetence; not maliciously slandering your language. Feel free to make a pull request here!
It's interesting Elixir and Gleam, two functional BEAM languages, both have only 15 keywords. Elixir provides macros which are quite powerful, such as for providing words that feel like keywords or for writing a DSL; Gleam just has Louis holding off on adding metaprogramming. Fwiw I personally hope Elixir does more cool stuff with macros and Gleam never gets them.
As a Go talk says there's a danger of languages trying to do everything
Convergence
Attended Lang.Next conference last year (2014).
Heard talks about new versions of Java, JavaScript (ECMAScript), Typescript, C#, C++, Hack (PHP), and more.
These languages actively borrow features from one another.
They are converging into a single huge language.
I will get into this more in another post but if there's a problem you can't solve using your language's primitives, rather than add more features to your language, the right response might be to make a new one with the set of features you want. Of course this might not be possible if you need to use existing codebases or libraries, and making a new language takes a lot of effort and ecosystem development.
The benefits though is keeping the language simple, with features that compose well together instead of providing multiple ways to do the same thing, and prevents "each programmer using a different subset of the language".
Now, you definitely can jerk too hard about about having a simple language with a tiny number of keywords. For example Go has no while keyword: is for true really simpler or easier than while true? There are definitely cases where it's not simple but simplistic.
Still people like to say simplicity is fake, "programs in [other language] contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of [my language]", etc., and idk, these people and sayings may be correct that the work that they are doing requires all the power of their language, but at the same time other people might be doing different work that doesn't require such power.
Bonus question: guess which two languages have the highest number of overlapping keywords? (click)
number of overlapping keywords:
52 keywords in TypeScript are also in C#
47 keywords in Groovy are also in Java
45 keywords in Dart are also in TypeScript
45 keywords in Dart are also in C#
45 keywords in Kotlin are also in C#
41 keywords in Groovy are also in C#
40 keywords in Groovy are also in TypeScript
40 keywords in F# are also in C#
39 keywords in OCaml are also in F#
39 keywords in Java are also in C#
39 keywords in Swift are also in C#
38 keywords in Java are also in TypeScript
38 keywords in Kotlin are also in TypeScript
37 keywords in JavaScript are also in TypeScript
36 keywords in PHP are also in TypeScript
If you guessed JavaScript - TypeScript, fair enough! But TypeScript - C# actually makes a lot of sense:
a) C# has a ton of keywords so there's a lot of opportunity for overlap, and b) Anders Hejlsberg designed both.
Maybe % of one language in another is more intuitive in some ways:
percent (of smaller language) of overlapping keywords:
100.0% of keywords in JavaScript are also in TypeScript
86.49% of keywords in JavaScript are also in Dart
82.46% of keywords in Groovy are also in Java
80.00% of keywords in Elixir are also in Ruby
78.38% of keywords in JavaScript are also in C#
75.68% of keywords in JavaScript are also in Groovy
73.91% of keywords in Lua are also in Ruby
71.93% of keywords in Groovy are also in C#
70.27% of keywords in JavaScript are also in Java
70.18% of keywords in Groovy are also in TypeScript
70.00% of keywords in MATLAB are also in PHP
69.77% of keywords in VBA are also in Visual Basic (.Net)
69.64% of keywords in OCaml are also in F#
69.57% of keywords in Lua are also in Delphi
69.57% of keywords in Lua are also in F#
I made no attempt to match keywords that do the same thing such as "else if" and "elif" (I believe you don't see C - C++ because of the lang version text preventing matches), and sharing literal words does not mean languages are the same (if you know PHP you already know 70% of MATLAB!)