Comparative Programming Languages
Language Comparison: Scheme, Smalltalk, Python, Ruby, Perl, Prolog, ML, C++/STL, Java
CS 363 Spring 2005 GMU 2
Fundamentals of Functional Programming Languages
• The objective of the design of a functional programming language (FPL) is to mimic mathematical functions to the greatest extent possible
• The basic process of computation is fundamentally different in a FPL than in an imperative language
– In an imperative language, operations are done and the results are stored in variables for later use
– Management of variables is a constant concern and source of complexity for imperative programming
• In an FPL, variables are not necessary, as is the case in mathematics
CS 363 Spring 2005 GMU 3
Fundamentals of Functional Programming Languages
• In an FPL, the evaluation of a function always produces the same result given the same parameters– This is called referential transparency
CS 363 Spring 2005 GMU 4
Lisp
• Lisp – based on lambda calculus (Church)– Uniform representation of programs and data
using single general data structure (list)– Interpreter based (written in Lisp)– Automatic memory management– Evolved over the years– Dialects: COMMON LISP, Scheme
5
Smalltalk – Object Orientation• Smalltalk – a dynamically typed object oriented
programming and functional language designed at Xerox PARC by Alan Kay, Dan Ingalls, Ted Kaehler, Adele Goldberg, during the 1970s. – Released as Smalltalk-80
– Influenced the development of languages such as Objective-C, Java and Ruby
– Everything is an object
– Everything is available for modification. If you want to change the IDE, you can do it
– Types are dynamic -- you don't have to define types in the code
– Garbage collection is built in, invisible to the developer.
6
Squeak• Squeak is an open, highly-portable
Smalltalk-80 implementation whose virtual machine is written entirely in Smalltalk – The image below was created in Squeak, and illustrates
several of Squeak's abilities, including the ability to scale and rotate bitmap images at any colour depth, anti-aliased TrueType fonts and vector graphics
7
Ruby• Ruby – combines syntax inspired by Python
and Perl with Smalltalk-like object-oriented features – Ruby is an interpreted language.
– Created by Yukihiro "Matz" Matsumoto, started working on Ruby in Feb. 1993 and released it to the public in 1995.
– Name chosen to reflect the language's Perl heritage.
– Designed Ruby to follow the principle of least surprise - the language should be free from traps and inconsistencies of other languages
8
Python• Python is an interpreted, interactive
programming language created by Guido van Rossum in 1990 – Originally as a scripting language for Amoeba OS
capable of making system calls.
– Amoeba distributed operating system is a microkernel-based research operating system written by Andrew S. Tanenbaum at Vrije Universiteit
– The aim of the project was to build a timesharing system that appeared to the user as a single machine even though it was running on multiple machines.
9
Python• Python
– Often compared to Tcl, Perl, Scheme, Java, and Ruby
– Developed as an open source project, managed by the non-profit Python Software Foundation.
– Python is a multi-paradigm language, like Perl, Oz or C++ and unlike Smalltalk or Haskell
– Rather than forcing coders to adopt one particular style of coding, it permits several
– Object orientation, structured programming, functional programming are all supported
– Python is dynamically type-checked and uses garbage collection for memory management
– origin of the name - after the television series Monty Python's Flying Circus
10
Python
• Python (from wikipedia)– Many similarities to Perl
– However, Python's designers reject Perl's exuberant syntax in favor of a more spare, less cluttered one
– As with Perl, Python's developers expressly promote a particular "culture" or ideology (http://python.org/dev/culture.html) based on what they want the language to be, favoring language forms they see as "beautiful", "explicit" and "simple".
– Although Python is sometimes classified as a "scripting language", it has been used to develop many large software projects such as the Zope application server
CS 363 Spring 2005 GMU 11
Scheme (dr scheme, guile)
(define (gcd u v) (if ( = v 0) u (gcd v (remainder u v)) ))
(define (reverse l) (if (null? l) l (append (reverse (cdr l))(list (car l))) ))
CS 363 Spring 2005 GMU 12
Scheme (dr scheme, guile)
Using guile (gnu scheme):
(load "slides.scm")(gcd 56 108) --> 4(reverse '(2 3 556)) --> (556 3 2)
13
Common Lisp (clisp)(defun mygcd (u v)
(if (= v 0)
u
(mygcd v (rem u v))
)
)
(defun myreverse (l)
(if (null l) l
(append (myreverse (cdr l))(list (car l)))
)
)
;; (load "slides.lsp"), (mygcd 56 108) --> 4
;; (myreverse '(2 3 556)) --> (556 3 2)
14
Smalltalk (Squeak - inisqueak)
myGcd: numTwo
" 112 myGcd: 224 --> 112”
(numTwo = 0) ifTrue: [^self].
^numTwo myGcd: self \\ numTwo.
myReverse
"#(1 2 3 43 a b) myReverse -> ($b $a 43 3 2 1 )"
(self size = 0) ifTrue: [^self].
^self allButFirst myReverse,
self first asOrderedCollection.
15
Gnu-Smalltalk – gst
!SequenceableCollection methodsFor: 'algorithms'!
"Or use Array, but that limits your objects."
myCount
" #(1 2 3 $a $b $c myCount! --> 6
In gst: Filestream inFile: count.st "
(self size = 0) ifTrue: [^0].
^(1 + (self copyFrom: 2) myCount).
!
16
Gnu-Smalltalk – gst (cont.)
myReverse
"#(1 2 3 43 a b) myReverse -> » ($b $a 43 3 2 1 )"
| temp |
(self size = 0) ifTrue: [^self].
temp := OrderedCollection new: 1.
temp add: self first.
^(self copyFrom: 2) myReverse, temp.
!!
17
Gnu-Smalltalk – gst (cont.)
!Number methodsFor: 'algorithms'!
myGcd: numTwo
"120 myGcd: 200! --> 40"
(numTwo = 0) ifTrue: [^self].
^numTwo myGcd: self \\ numTwo.
!!
18
Ruby (ruby)def myGcd(numOne, numTwo)
if numTwo == 0
return numOne
end
return myGcd(numTwo, numOne % numTwo)
end
def myReverse(list)
if list.length == 1
return list
end
return myReverse(list[1..list.length-1]).concat([list[0]])
end
19
Ruby - “Class version”count.rb
class Integer
def myGcd(numTwo)
if numTwo == 0
return self
else
return numTwo.myGcd(self % numTwo)
end
end
end
- load “file.rb” into the Ruby interpreter (eval.rb)
- 120.myGcd(500) --> 20
20
Ruby - “Class version”class Integer
def greet
print "Hello world\n"
end
def plus(numTwo)
return self + numTwo
end
def times(numTwo)
return self * numTwo
end
end
- load “file.rb” into the Ruby interpreter (eval.rb)
- 120.greet --> “Hello..”, 3.plus(4).times(5) -> 35
21
Ruby (non-class vers.)def myCount (mylist)
if mylist.length == 0
return 0
else
return 1 + myCount(mylist[1..mylist.length-1])
end
end
print "Length of [1,2,3,4,5,6]= ",
myCount([1,2,3,4,5,6]), "\n"
To run: ruby count.rb
22
Ruby (class vers.)class Array
def myCount
if self.length == 0
return 0
else
return 1 + self[1..self.length].myCount
end
end
end
This version is “object oriented”...
[3,4,5,6,7,78].myCount --> 6
23
Python (python)def myGcd(numOne, numTwo):
if(numTwo == 0):
return numOne
return myGcd(numTwo, numOne % numTwo)
def myReverse(mylist):
if len(mylist) == 1:
return mylist
return myReverse(mylist[1:len(mylist)]) + myReverse([mylist[0]])
24
Python (python)def myCount (mylist):
if len(mylist) == 0:
return 0
else:
return 1 + myCount(mylist[1:len(mylist)])
print "Length of [1,2,3,4,5,6]= ", myCount([1,2,3,4,5,6])
To run: python count.py
25
Perlsub gcd {
if ($_[1] == 0) {
return $_[0];
} else {
return gcd($_[1], $_[0] % $_[1]);
}
}
sub count {
my @ls; @ls = @_;
if (scalar(@ls) == 1) { 1; }
else {
count(@ls[1..$#ls]) + 1;
}
}
26
Perlsub myReverse {
my @templis;
if (scalar(@_) == 0) {
return ();
} else {
@templis = myReverse(@_[1..$#_]);
push(@templis, $_[0]);
return @templis;
}
}
27
Prologgcd(Num1, 0, Num1).
gcd(Num1, Num2, GCD) :-
Rem is Num1 mod Num2,
gcd(Num2, Rem, GCD).
count([],Total , Total).
count([_|Rest], Counter, TotalCount) :-
NewCount is Counter + 1,
count(Rest, NewCount,TotalCount).
/*
consult('gcd.pl').
gcd(28, 100, X).
count([3,4,5,6,7],0, X).
*/
28
Prologappend([],List, List).
append([First|Rest], List2, [First|List3]) :-
append(Rest, List2, List3).
myreverse([],[]).
myreverse([First|[]],[First]).
myreverse([First|Rest], NewList) :-
myreverse(Rest, ReversedList),
append(ReversedList,[First], NewList).
/*
?- consult('reverse.pl').
?- myreverse([11,23, 0,42,18,90, 1],X).
X = [1, 90, 18, 42, 0, 23, 11]
*/
29
ML (sml)fun gcd(num1, 0) = num1
| gcd(num1,num2) =
gcd(num2, num1 mod num2);
fun count([]) = 0
| count(first::rest) = 1 + count(rest);
(*
- use "gcdcount.sml";
- gcd(28, 124);
val it = 4 : int
- count([45,2,7,8,1,23,18]);
val it = 7 : int
*)
30
ML (sml)fun reverse(L) =
if L = nil then nil
else reverse(tl(L)) @ [hd(L)];
fun reverse2([]) = []
| reverse2(first::rest) =
reverse2(rest) @ [first]
(* [] can be used for nil
- use "reverse.sml";
- reverse2([1,2,3,4]);
val it = [4,3,2,1] : int list
-val x = [[1,2],[3,4]] : int list list
- reverse(x); - val it = [[3,4],[1,2]] : int list list *)
31
C++
int gcd(int num1, int num2) {if (num2 == 0)
return num1;else
return gcd(num2, num1 % num2);}
32
C++ (STL)
int count(list<int> lis) {if (lis.size() == 0)
return 0;else {
lis.pop_front();return 1 + count(lis);
}}
33
C++ (STL)list<int> reverse(list<int> lis) {
if (lis.size() == 0)return lis;
else {int first = *lis.begin();lis.pop_front();list<int> reversed;reversed = reverse(lis);reversed.push_back(first);return reversed;
}}
34
Javaint gcd(int num1, int num2) {
if (num2 == 0) return num1;
else return gcd(num2,num1 % num2);
}
35
Javaint count(List lis) {
if (lis.isEmpty()) // or lis.size() == 0
return 0;else
return 1 + count(lis.subList(1, lis.size()));
}
36
Java
List reverse(List lis) {if (lis.isEmpty()) return lis;else {
Integer first = (Integer)lis.get(0);
List temp = reverse(lis.subList(1,lis.size()));
temp.add(temp.size(), first);return temp;
}}
Squeak Browser Window – Lists classes and methods in classes
Squeak Workspace WindowTo “run” each line, middle-button click, choose
“do it” or “print it”
Squeak Transcript WindowTo “run” each line, middle-button click, choose
“do it” or “print it”
Gnu Smalltalk Browser Window
Gnu Smalltalk, X11Worksheet and Transcript
Worksheet window Transcript window
To “run” a line, right click and choose “do it” and/or “print it”
Gnu Smalltalk - gst
Note the use of “!” at the end of each line.
Also, printNl is specific to gst.
Ruby – example run, see count.rb
Ruby – example run from eval.rb
Python – example run, see count.rb