Friday, January 14, 2011

How many keywords in your source code? Round 2



Last year, in July 2011, I wrote a post about How many keywords do you type in your code?.

"Have you ever wondered how many keywords (reserved words) do you type in your programs? Can you type more or type less without changing what your program does? Can you change programming language and save some typing? And if so, to which language?". 

Back then, I tried to answer those questions by showing some comparative graphics with the number of keywords needed to build 2 versions (minimal and verbose) of the same little program in 20 different programming languages (C#, VB.NET, C++/CLI, F#, Boo, Phalanger, IronPython, IronRuby, Delphi Prism, Zonnon, Nemerle, Cobra, JScript.NET, Java, JavaFX, Groovy, Jython, JRuby, Fantom, Scala).


The program I chose was an OO version of the famous Hello World (Archive posts June-July 2010) and had the following structure:

// OO Hello World
    // Import,using,etc.
    // Class
        // Field
        // Constructor
        // Method
    // Program
        // Instantiate Class
        // Call Method = OUTPUT (Hello, World!)

Finally, I added some comments and thoughts about the results, but... What if we do the same with a bigger example? Will the results be more or less the same if I a more elaborated program is used to do the comparison? Do the most verbose language and the most minimalistic of the previous post will still hold the title?

That's exactly what this new post is all about! :) a new comparison on a more elaborated, still small, program using many more language constructs following the sample rules of the previous comparison:

  • 2 Versions Minimal and Verbose.
  • 21 Programming Languages (the previous 20 + Gosu).
  • Primitive Types such as int, float, double, string not considered as keywords.
  • Same OO program and structure (taken from series Language's Basics by Example).
  • OO Hello World was small enough to count by hand, but this time I created a little script written in Python 3 that does the automatic counting for me :) (source code to be provided in my next post). 

// Language Basics
    // Greet Class
        // Fields or Attributes
        // Properties
        // Constructor
        // Overloaded Constructor
        // Method 1
            // "if-then-else" statement
        // Method 2
            // "for" statement
        // Overloaded Method 2.1
            // "while" statement
        // Overloaded Method 2.2
            // use Date Class
            // "switch/case" statement

    // Console Program
        // Define object of type Greet 
        // Instantiate Greet. Call Constructor
        // Call Set Properties
        // Call Method 2
        // Call Method 2.1 and Get Properties
        // Call Method 2.2
        // Stop and exit - Read Input From Console

Here below th graphs! Click on the images to enlarge.

Total Keywords by Language

Language Keywords
IronPython 31
Jython 31
IronRuby 38
JRuby 38
Scala 40
Fantom 46
Java 50
Zonnon 50
Gosu 53
Groovy 57
Nemerle 59
Boo 66
JavaFX 70
JScript.NET 75
C++/CLI 84
Phalanger 92
F# 97
C# 102
Delphi Prism 134
VB.NET 137
Cobra 139



Version 1 (Minimal)

Language Keywords
VB.NET 130
Delphi Prism 94
Phalanger 89
Cobra 79
JScript.NET 72
Groovy 72
Gosu 72
C# 69
Boo 68
Zonnon 66
Java 65
JavaFX 64
C++/CLI 59
Jython 51
IronPython 48
JRuby 46
IronRuby 46
Fantom 46
F# 41
Scala 37
Nemerle 33


Version 2 (Verbose)

Language Keywords
VB.NET 169
Delphi Prism 134
JScript.NET 118
Gosu 114
Boo 114
Cobra 109
JavaFX 105
Phalanger 103
Java 103
C# 103
Groovy 101
C++/CLI 101
Zonnon 90
Fantom 80
Nemerle 67
F# 54
Jython 53
IronPython 50
JRuby 48
IronRuby 48
Scala 41



Both (Minimal and Verbose) 

Language Minimal Verbose
VB.NET 130 169
Delphi Prism 94 134
Phalanger 89 103
Cobra 79 109
JScript.NET 72 118
Groovy 72 101
Gosu 72 114
C# 69 103
Boo 68 114
Zonnon 66 90
Java 65 103
JavaFX 64 105
C++/CLI 59 101
Jython 51 53
IronPython 48 50
JRuby 46 48
IronRuby 46 48
Fantom 46 80
F# 41 54
Scala 37 41
Nemerle 33 67



Compare Basics and HelloWorld (Minimal and Verbose) 

Language| Basics Minimal| Basics Verbose| Basics Differ| Hello Minimal| Hello Verbose| Hello Differ|
VB.NET 13016939243410
Delphi Prism 941344035394
Phalanger 891031410166
Cobra 79109309145
JScript.NET 72118467158
Groovy 72101295116
Gosu 72114425138
C# 691033410155
Boo 681144671710
Zonnon 66902416215
Java 651033812164
JavaFX 641054151510
C++/CLI 591014211165
Jython 51532462
IronPython 48502462
JRuby 46482660
IronRuby 46482660
Fantom 468034594
F# 4154135127
Scala 374145105
Nemerle 3367349167


CONCLUSIONS

As with the previous post, we can still notice the 3 main groups of languages:
1. Scripting/Dynamic Languages (Python, Ruby, Groovy, etc.) fewer keywords
2. Functional Languages (F#, Scala, Nemerle, etc.) more or less than the previous group
3. Imperative/Static Languages (C#, C++, VB.NET, Java, etc.) more keywords

We can also see that the scripting/dynamic languages are the ones that define the fewer keywords and that's probably the reason why there are few or no difference in the number of keywords typed between the 2 versions of the same program (see latest graph above).

The difference between the number of keywords of the most verbose and the most minimalistic program is of:
Basics Minimal: VB.NET 130 vs Nemerle 33 (97 keys of difference)
Basics Verbose: VB.NET 169 vs Scala 41 (128 keys of difference)
Big differences... and they could be much bigger if we include primitive types as keywords (because they are keywords, but were excluded for this comparison)

When comparing a small program such as the OO Hello World in which didn't use many language constructs we still saw a big difference between the most verbose and the most minimalistic languages. That is still true when many more statements and constructs are added to the code as in the case of: Delphi Prism and VB.NET, however, this time we can clearly see that the most verbose language is not Delphi Prism but VB.NET!!!

So, VB.NET congratulations! You are the most extra-typing language among the .NET and Java languages. I guess that's why Visual Studio 2010 auto-completes all the closing blocks keywords :D so you don't need to type that many... I'm wondering what about those programmers that love to code in raw text using notepad(++?)... I guess those brave of hearth do not program using VB. Am I right?

Nevertheless, I'm very curious about running the keywords counting on a Real Life program (hundreds-thousands lines of code) and see what the result is.

And now, about the most minimalistic language? Well, this time was Nemerle, followed by Scala and F#. The 3 languages are multi-paradigm languages, but are mainly inspired by the Functional ones, so we can probably assume that functional languages use less keywords, less typing even if using their OO syntax features; that's probably why there are lots of blog posts about the difference in amount of code between Scala and Java; of course they always compare Java's Imperative syntax vs Scala's Functional syntax, which is fare enough because Scala is meant to be used as a functional language. Right? So, in summary, using OO or Functional syntax, you will usually have smaller programs. Of course, that depends how you write code and if you use, let's say, match-case instead of if-then-else.

So what happened to the Scripting languages? weren't they the ones with smaller keywords sets? and I'm not talking about Groovy because remember that Groovy needs to be Java syntax compatible, but Python and Ruby?

Let's have a look:

Ruby 48
module 1
class 1
def 11 # this is understandable
end 17 # and here is where the most keyword go! 
if 1
return 2
else 2
for 1
in 1
while 1
do 1
case 1 # using the case construct also requires lots of keys because 
when 4 # it uses when and then for each case you want to validate against
then 4 #

IronPython 50
import 2
from 1
class 1
def 12  # this is understandable
return 5
if 2
else 2
for 1
in 1
print 4  # print is a keyword but other languages use  
           # Console.WriteLine | System.out.println 
while 1
or 16 # and here is where the most keyword go because 
           # python has no switch | case | match syntax 
elif 2


What else... oh yes. Verbosity of the language has nothing to do with its elegance or expressiveness (for instance Delphi Prism vs Scala|F#).

Finally, counting keywords in your code is probably not relevant, because it will vary a lot between programs, styles, paradigms, if code was automatically generated, manually typed, and so on.
In my case I used the 2 edges to compare the "Minimal" and "Verbose", but in real coding a combination based on the above might be used.

That's pretty much it.

Here below I added the counting results for all the 21 languages in case you wonder which keywords




Basics MinimalBasics Verbose
Boo 68Boo 114
import 1
class 1
as 17
get 3
return 5
set 3
def 6
constructor 2
self 4
private 1
if 2
else 2
for 1
in 1
while 1
or 16
elif 2
namespace 1
import 1
private 5
class 1
as 24
public 9
get 3
return 5
self 28
set 3
def 7
constructor 2
if 2
else 2
for 1
in 1
while 1
or 16
elif 2

Basics MinimalBasics Verbose
Cobra 79Cobra 109
class 2
var 3
pro 3
as 12
get 3
return 5
set 3
cue 2
base 2
def 5
is 1
private 1
if 1
else 2
for 1
in 1
print 4
while 1
branch 1
on 4
or 20
any 1
to 1
use 1
namespace 1
class 2
is 12
public 10
var 3
as 18
pro 3
get 3
return 5
set 3
cue 2
base 2
def 5
private 1
if 1
else 2
for 1
in 1
print 4
while 1
branch 1
on 4
or 20
shared 1
any 1
to 1

Basics MinimalBasics Verbose
C++/CLI 59C++/CLI 101
using 1
namespace 1
class 1
public 2
property 3
return 5
void 6
this 3
private 1
if 1
else 1
for 1
while 1
switch 1
case 24
break 5
default 1
gcnew 1
using 1
namespace 2
private 5
class 1
public 14
property 3
return 6
this 27
void 6
if 1
else 1
for 1
while 1
switch 1
case 24
break 5
default 1
gcnew 1

Basics MinimalBasics Verbose
C# 69C# 103
using 1
class 2
public 8
get 3
return 5
set 3
value 3
this 3
if 1
else 1
void 4
for 1
while 1
switch 1
case 24
break 5
default 1
static 1
new 1
using 1
namespace 1
internal 2
class 2
private 4
public 9
get 3
return 5
this 29
set 3
value 3
if 1
else 1
void 4
for 1
while 1
switch 1
case 24
break 5
default 1
static 1
new 1

Basics MinimalBasics Verbose
DelphiPrism 94DelphiPrism 134
namespace 1
interface 1
uses 1
type 2
class 4
private 1
method 14
public 2
property 3
read 3
write 3
constructor 4
end 17
array 2
of 3
implementation 1
begin 13
if 1
then 1
result 2
else 2
for 1
to 2
step 1
do 2
var 3
while 1
case 1
new 1
exit 1
namespace 1
interface 1
uses 1
type 2
public 11
class 4
private 6
var 6
method 14
property 3
read 3
write 3
constructor 4
end 17
array 2
of 3
implementation 1
begin 13
self 23
if 1
then 1
result 2
else 2
for 1
to 2
step 1
do 2
while 1
case 1
new 1
exit 1

Basics MinimalBasics Verbose
Fantom 46Fantom 80
class 2
private 4
return 5
it 3
new 1
if 1
else 1
for 1
while 1
switch 1
case 24
default 1
static 1
internal 1
class 2
private 4
public 9
return 5
this 24
it 3
new 1
if 1
else 1
for 1
while 1
switch 1
case 24
default 1
static 1

Basics MinimalBasics Verbose
F# 42F# 54
open 1
type 1
let 9
mutable 4
member 7
with 4
and 3
new 2
private 1
if 1
then 1
else 1
for 1
to 2
do 2
while 1
match 1
namespace 1
open 1
type 1
public 8
class 1
let 9
mutable 4
member 7
with 4
and 3
new 2
private 1
if 1
then 1
else 1
for 1
to 2
do 2
while 1
match 1
end 1
module 1

Basics MinimalBasics Verbose
Gosu 72Gosu 114
uses 4
class 1
var 8
property 6
get 4
return 5
set 3
private 1
function 4
else 1
for 1
while 1
new 3
switch 1
case 24
break 4
default 1
uses 4
public 12
class 1
private 4
var 8
property 6
get 4
return 5
this 27
set 3
function 4
else 1
for 1
while 1
new 3
switch 1
case 24
break 4
default 1

Basics MinimalBasics Verbose
Groovy 72Groovy 101
class 1
private 4
def 20
return 5
this 3
if 1
else 1
for 1
in 2
while 1
new 3
switch 1
case 24
break 4
default 1
package 1
public 12
class 1
private 4
return 5
this 29
void 6
def 3
if 1
else 1
for 1
in 2
while 1
new 3
switch 1
case 24
break 5
default 1

Basics MinimalBasics Verbose
IronPython 48IronPython 50
from 1
import 1
class 1
def 11
return 5
if 2
else 2
for 1
in 1
print 4
while 1
or 16
elif 2
import 2
from 1
class 1
def 12
return 5
if 2
else 2
for 1
in 1
print 4
while 1
or 16
elif 2

Basics MinimalBasics Verbose
IronRuby 46IronRuby 48
class 1
def 11
end 16
if 1
return 2
else 2
for 1
in 1
while 1
do 1
case 1
when 4
then 4
module 1
class 1
def 11
end 17
if 1
return 2
else 2
for 1
in 1
while 1
do 1
case 1
when 4
then 4

Basics MinimalBasics Verbose
Java 65Java 103
package 2
import 2
class 2
private 4
return 5
void 7
this 3
if 1
else 1
for 1
while 1
switch 1
case 24
break 5
default 1
public 2
static 1
new 2
package 2
import 2
public 14
class 2
private 4
return 5
this 29
void 7
if 1
else 1
for 1
while 1
switch 1
case 24
break 5
default 1
static 1
new 2

Basics MinimalBasics Verbose
JavaFX 64JavaFX 105
import 4
class 1
var 6
function 11
return 5
init 1
if 5
else 5
for 1
in 2
while 1
def 1
new 1
or 20
package 1
import 4
public 11
class 1
var 6
function 11
return 5
this 29
init 1
if 5
else 5
for 1
in 2
while 1
def 1
new 1
or 20

Basics MinimalBasics Verbose
JRuby 46JRuby 48
class 1
def 11
end 16
if 1
return 2
else 2
for 1
in 1
while 1
do 1
case 1
when 4
then 4
module 1
class 1
def 11
end 17
if 1
return 2
else 2
for 1
in 1
while 1
do 1
case 1
when 4
then 4

Basics MinimalBasics Verbose
JScript.NET 72JScript.NET 118
import 1
class 1
var 7
function 12
get 3
return 5
set 3
this 3
private 1
if 1
else 1
for 1
while 1
switch 1
case 24
break 5
default 1
new 1
import 1
package 1
public 12
class 1
private 4
var 7
function 13
get 3
return 5
this 29
set 3
if 1
else 1
void 3
for 1
while 1
switch 1
case 24
break 5
default 1
new 1

Basics MinimalBasics Verbose
Jython 51Jython 53
from 2
import 2
class 1
def 11
return 5
if 2
else 2
for 1
in 2
print 4
while 1
or 16
elif 2
import 3
from 2
class 1
def 12
return 5
if 2
else 2
for 1
in 2
print 4
while 1
or 16
elif 2

Basics MinimalBasics Verbose
Nemerle 33Nemerle 67
using 1
class 1
mutable 5
public 8
this 5
private 1
if 1
else 1
void 3
for 1
while 1
def 2
match 1
_ 2
using 1
namespace 1
internal 1
class 1
private 4
mutable 6
public 10
this 29
if 1
else 1
void 4
for 1
while 1
def 1
match 1
_ 2
module 1
static 1

Basics MinimalBasics Verbose
Phalanger 89Phalanger 103
namespace 1
class 2
private 4
function 12
return 5
this 24
if 1
else 1
for 1
echo 4
while 1
switch 1
case 24
break 4
default 1
static 1
new 1
exit 1
namespace 2
class 2
private 4
public 11
function 12
return 6
this 24
if 1
else 1
for 1
echo 4
while 1
switch 1
case 24
break 5
default 1
static 1
new 1
exit 1

Basics MinimalBasics Verbose
Scala 37Scala 41
import 1
class 1
private 4
var 4
def 12
this 2
if 1
else 1
for 1
while 1
val 2
match 1
case 5
new 1
package 1
import 2
class 1
private 4
var 4
def 13
this 2
if 1
else 1
for 1
while 1
val 2
match 1
case 5
object 1
new 1

Basics MinimalBasics Verbose
VB.NET 130VB.NET 169
Imports 1
Friend 2
Class 2
Private 4
As 22
Property 6
Get 6
Return 5
End 21
Set 6
ByVal 11
Sub 12
New 3
Function 2
If 2
Then 1
Else 2
For 1
To 5
Next 1
Dim 3
While 2
Select 2
Case 6
Module 2
Imports 1
Namespace 2
Friend 2
Class 2
Private 4
As 22
Public 9
Property 6
Get 6
Return 5
Me 27
End 22
Set 6
ByVal 11
Sub 12
New 3
Function 2
If 2
Then 1
Else 2
For 1
To 5
Next 1
Dim 3
While 2
Select 2
Case 6
Module 2

Basics MinimalBasics Verbose
Zonnon 66Zonnon 90
module 1
import 1
type 1
object 1
var 5
procedure 10
begin 12
return 5
end 16
if 1
then 1
else 2
for 1
to 2
do 2
while 1
case 1
of 1
new 1
exit 1
module 1
import 1
type 1
object 1
var 5
procedure 10
begin 12
return 5
self 24
end 16
if 1
then 1
else 2
for 1
to 2
do 2
while 1
case 1
of 1
new 1
exit 1

5 comments:

  1. Do you mind if I use some of your graphs, with attribution to this blog entry, for a poster at the SIGCSE conference on using Scala in early CS courses?

    ReplyDelete
  2. Hi Mark,

    Feel free to do it. You can use any info you find useful from this blog. A link to it would be appreciated :)

    Carlos

    ReplyDelete
  3. In Ruby, you can use newlines instead of `then` inside a `case` block.
    This would reduce the keyword count and arguably make it more readable too.

    ReplyDelete
    Replies
    1. Thanks for your feedback. I will have a look and update the code/graphs if needed.

      Delete