Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level...

61
Sard: An Object-Functional Programming Language Hugo Svallfors May 9, 2011 Master’s Thesis in Computing Science, 15 credits Supervisor at CS-UmU: Frank Drewes Examiner: Pedher Johansson Ume ˚ a University Department of Computing Science SE-901 87 UME ˚ A SWEDEN

Transcript of Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level...

Page 1: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

Sard: An Object-FunctionalProgramming Language

Hugo Svallfors

May 9, 2011Master’s Thesis in Computing Science, 15 credits

Supervisor at CS-UmU: Frank DrewesExaminer: Pedher Johansson

Umea UniversityDepartment of Computing Science

SE-901 87 UMEASWEDEN

Page 2: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing
Page 3: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

Abstract

This bachelor’s degree concerns the specification of a new programming lan-guage. This language, called Sard, is a backwards-incompatible new version ofthe existing language Scala. Sard, like Scala, is a high-level object-functionallanguage. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing some constraints on the language’s design. Since this necessitates breakingbackwards compatibility with Scala, the opportunity to disregard it is usedto fix some of the author’s irritations with the language. This degree mostlyfocuses on deciding on the exact changes to Scala, and on the overall design,rather than on implementing a compiler for the language. A reason for thisis that the bachelor’s degree provides insufficient time to properly implementand debug a compiler. Another is the desirability of pushing changes to thelanguage as early into the design process as possible. Preferably, almost allchanges to the language should occur before any compiler code has been writ-ten.

The design eventually produced gets rid of some known issues stemmingfrom the JVM, like null pointers, non-reified generics and single inheritance.Several features of Scala, like self-type annotations and infix syntax for methodsare scrapped. Others, like pattern matching, are generalized. Some changes tothe syntax are also made, particularly in the areas of closures, pattern matchingand object construction.

As of yet, this language has no implementation, and in future work, thismust be rectified. Sard also requires calling compatibility with another pro-gramming language, but this remains to be specified. Nevertheless, Sard con-stitutes a promising refinement of an already great programming language, andit is hoped that Sard will fix the few remaining issues with Scala’s design.

Page 4: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

ii

Page 5: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

Contents

1 Introduction 1

1.1 Problem Description . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Feature Set 5

2.1 Type Inference . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2 Trait Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2.1 Symmetric Inheritance . . . . . . . . . . . . . . . . . . . 6

2.2.2 Removal of Single Inheritance . . . . . . . . . . . . . . . 6

2.3 Compound Types . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.4 Subclassable Closures . . . . . . . . . . . . . . . . . . . . . . . 7

2.5 Underscore Closures . . . . . . . . . . . . . . . . . . . . . . . . 8

2.6 Tuples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.7 Reified Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.8 Type Members . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.9 ML-Like Pattern Matching . . . . . . . . . . . . . . . . . . . . 11

2.10 Null Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.11 Syntactic Sugar for Constructors . . . . . . . . . . . . . . . . . 13

2.12 All statements return a value . . . . . . . . . . . . . . . . . . . 14

2.13 Default Values for Parameters . . . . . . . . . . . . . . . . . . . 15

2.14 Method Overloading . . . . . . . . . . . . . . . . . . . . . . . . 15

2.15 Companion Objects . . . . . . . . . . . . . . . . . . . . . . . . 15

2.16 Infix Syntax for Methods . . . . . . . . . . . . . . . . . . . . . 16

2.17 Structural Subtyping . . . . . . . . . . . . . . . . . . . . . . . . 17

2.18 Call-by-value, -by-need and -by-name . . . . . . . . . . . . . . . 18

2.19 Module and Import System . . . . . . . . . . . . . . . . . . . . 18

2.20 VarArgs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2.21 Local Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

iii

Page 6: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

iv CONTENTS

2.22 For-Each Loops and Enumerations . . . . . . . . . . . . . . . . 19

2.23 XML-Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2.24 Tail-Call Optimization . . . . . . . . . . . . . . . . . . . . . . . 20

2.25 Annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

2.26 Uniform Access . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

2.27 Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

2.28 Variance Annotations . . . . . . . . . . . . . . . . . . . . . . . 21

2.29 Multi-Line Strings . . . . . . . . . . . . . . . . . . . . . . . . . 22

2.30 Named Arguments . . . . . . . . . . . . . . . . . . . . . . . . . 22

2.31 Optional Dynamic Typing . . . . . . . . . . . . . . . . . . . . . 22

2.32 Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

2.33 Existential Types . . . . . . . . . . . . . . . . . . . . . . . . . . 23

2.34 Self-Type Annotations . . . . . . . . . . . . . . . . . . . . . . . 24

2.35 Higher-Kinded Generics . . . . . . . . . . . . . . . . . . . . . . 24

2.36 Implicit Parameters and Conversions . . . . . . . . . . . . . . . 25

3 Syntax 27

3.1 Changes relative to Scala . . . . . . . . . . . . . . . . . . . . . 27

3.1.1 New Closure Syntax . . . . . . . . . . . . . . . . . . . . 27

3.1.2 The Removal Of ”new” Around Object Creation . . . . 28

3.2 Syntax Specification . . . . . . . . . . . . . . . . . . . . . . . . 28

4 Type System 35

4.1 Special Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

4.1.1 trait Any . . . . . . . . . . . . . . . . . . . . . . . . . . 36

4.1.2 trait Reference . . . . . . . . . . . . . . . . . . . . . . . 36

4.1.3 trait Value . . . . . . . . . . . . . . . . . . . . . . . . . 36

4.1.4 sealed trait Nothing . . . . . . . . . . . . . . . . . . . . 37

4.2 Primitive Traits . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

4.2.1 trait Showable . . . . . . . . . . . . . . . . . . . . . . . 37

4.2.2 trait Binary . . . . . . . . . . . . . . . . . . . . . . . . . 37

4.2.3 trait Hashable . . . . . . . . . . . . . . . . . . . . . . . 37

4.2.4 trait Equality[A] . . . . . . . . . . . . . . . . . . . . . . 38

4.2.5 trait Ordered[A] . . . . . . . . . . . . . . . . . . . . . . 38

4.2.6 trait Enumerable[A] . . . . . . . . . . . . . . . . . . . . 38

4.2.7 trait Exception . . . . . . . . . . . . . . . . . . . . . . . 38

4.2.8 trait Monoid[A] . . . . . . . . . . . . . . . . . . . . . . . 39

4.2.9 trait Numeric[A] . . . . . . . . . . . . . . . . . . . . . . 39

Page 7: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

CONTENTS v

4.2.10 trait Integral[A] . . . . . . . . . . . . . . . . . . . . . . . 39

4.2.11 trait Fractional[A] . . . . . . . . . . . . . . . . . . . . . 39

4.2.12 trait NumberConvertible . . . . . . . . . . . . . . . . . . 40

4.2.13 trait Bitwise[A] . . . . . . . . . . . . . . . . . . . . . . . 40

4.2.14 trait Floating[A] . . . . . . . . . . . . . . . . . . . . . . 40

4.3 Primitive Types . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

4.3.1 object System . . . . . . . . . . . . . . . . . . . . . . . . 41

4.3.2 class Type . . . . . . . . . . . . . . . . . . . . . . . . . . 41

4.3.3 sealed trait Ordering . . . . . . . . . . . . . . . . . . . . 41

4.3.4 class Lock . . . . . . . . . . . . . . . . . . . . . . . . . . 41

4.3.5 class Thread . . . . . . . . . . . . . . . . . . . . . . . . 42

4.3.6 class Array[Elem] . . . . . . . . . . . . . . . . . . . . . . 42

4.3.7 sealed trait Bool . . . . . . . . . . . . . . . . . . . . . . 42

4.3.8 class Char . . . . . . . . . . . . . . . . . . . . . . . . . . 43

4.3.9 sealed trait UnicodeCategory . . . . . . . . . . . . . . . 43

4.3.10 class SByte . . . . . . . . . . . . . . . . . . . . . . . . . 44

4.3.11 class Byte . . . . . . . . . . . . . . . . . . . . . . . . . . 45

4.3.12 class Short . . . . . . . . . . . . . . . . . . . . . . . . . 45

4.3.13 class UShort . . . . . . . . . . . . . . . . . . . . . . . . 45

4.3.14 class Int . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

4.3.15 class UInt . . . . . . . . . . . . . . . . . . . . . . . . . . 46

4.3.16 class Long . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4.3.17 class ULong . . . . . . . . . . . . . . . . . . . . . . . . . 47

4.3.18 class Float . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4.3.19 class Double . . . . . . . . . . . . . . . . . . . . . . . . . 48

4.3.20 class LongDouble . . . . . . . . . . . . . . . . . . . . . . 48

4.3.21 class IndexOutOfBounds . . . . . . . . . . . . . . . . . . 48

4.3.22 class IndexUndefined . . . . . . . . . . . . . . . . . . . . 49

4.3.23 class Overflow/class Underflow . . . . . . . . . . . . . . 49

4.3.24 class DivideByZero . . . . . . . . . . . . . . . . . . . . . 49

4.3.25 class IllegalArgument . . . . . . . . . . . . . . . . . . . 49

4.3.26 class OutOfMemory . . . . . . . . . . . . . . . . . . . . 49

4.3.27 class StackOverflow . . . . . . . . . . . . . . . . . . . . 49

4.3.28 class RefutedPattern[A] . . . . . . . . . . . . . . . . . . 49

Page 8: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

vi CONTENTS

5 Conclusions 51

5.1 Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . 51

5.2 Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

5.3 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

References 53

Page 9: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

Chapter 1

Introduction

About one and a half years ago, I decided I wanted to write a compiler. Ini-tially, this was a mere Scheme variant, with no real purpose other than myown education. However, as I learned more about programming languages theproject kept growing in scope until it was a new language. This language,called YStack[9], was a stack-based functional language.

Eventually, several faults were found with this design.[10] The stack-basedparadigm lends itself to highly unreadable code. With most variables being im-plicit on the stack, large parts of the language ended up being incomprehensibleeven to me.

Furthermore, the stack paradigm meant that operations only ever affectedthe top of the stack. Therefore, it became necessary to ”shuffle the stack”, i.emove variables so that the correct ones where on top. Between the above twoissues, the stack paradigm seemed like a flawed one.

At around this time, I started programming in Scala, and in a sense ”redis-covered” object orientation. Scala is a so-called object-functional language onthe Java virtual machine. Scala proves that one can program with objects with-out necessarily relying overmuch on mutable state or extremely verbose code.But more importantly, Scala also proves that object-orientation and functionalprogramming are not exclusive, and in fact have several useful synergies. Thesesynergies include, among others[4]:

1. That functional ADT’s and pattern matching can be implemented asclass hierarchies.

2. That functions themselves can be formulated as objects, and thus spe-cialized and/or subclassed.

3. With the addition of type members, Scala’s class system can subsumeML modules.

More generally, the creator of the language Martin Odersky remarks[6],functional programming makes it easier to build things from simple parts,

1

Page 10: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

2 Chapter 1. Introduction

whereas object- orientation makes it simple to extend complex systems. Toparaphrase this observation slightly, functional programming works best whenprogramming in the small, and object-orientation works best when program-ming in the large. When phrased like so, the potential synergy between thetwo becomes obvious: Why not make programming in the large and small easyby combining them?

While this foundational idea is sound, maybe even brilliant, it is limited byit’s implementation on the JVM.

Scala has from the outset been very closely tied to Java and the JVM.Already at it’s inception Scala was envisioned as a JVM language with full Javacalling compatibility. However, Odersky thinks that doing so was a ”double-edged sword”[4].

In doing so, they gained the strength of Java’s VM implementations, andvast amounts of library code that they would otherwise have had to writethemselves. But they also had to make several compromises with their designto preserve calling compatibility with Java. Odersky lists the lack of truevirtual classes, the adoption of null references and limited tail recursion amongthese.[4]

While I agree with the above list, in my humble opinion there are two moreissues that crop up because of Java: The presence of dynamic types and thenon-presence of unsigned integers.

As the reader may know, Java is about to have it’s first version update inquite some time. One item that is to be added to the language is optionaldynamic typing. Since Scala itself is an advanced statically typed language,having dynamic types would only weaken it’s guarantees of compile-time cor-rectness. Indeed, any static verification of any property goes right out thewindow as soon as dynamic types are introduced. As a direct consequence,previously catchable bugs will become run-time crashes instead, wasting theprogrammer’s time with trivial errors that could, in a proper type system, bediscovered automatically.

In addition, any program using dynamic types will be one to two orders ofa magnitude slower than one without. Nearly all optimizations rely on havingadvance information on types. Without that, only a few runtime optimizationslike JIT can be applied. And those can be applied in static languages as well.In conclusion, dynamic types will make software that uses them both buggyand slow, wasting the time of both man and machine at the same time.

Unfortunately, since Scala has to have calling compatibility with Java, theyare bound to implement any feature that Java does. Hence Scala will havedynamic types, in spite of the fact that it clashes with the languages generalemphasis on safety.

Java have also long lacked any form of unsigned integer. This means that itis impossible to efficiently express the invariant that one has a whole numberthat is not negative. This is a pattern that crops up quite a lot in many differentproblems. It also makes binary I/O inordinately difficult, when binary data isalmost always interpreted as unsigned.

Page 11: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

1.1. Problem Description 3

Odersky finishes his list of Java compromises by saying this:

”It would be interesting to see another unification of FP and OOPthat is less determined by existing technology.”

Hopefully, that’s where I come in.

1.1 Problem Description

To solve the aforementioned problems with Scala, a new programming languageis called for. One based on the object-functional idiom but removed from closedependence on the JVM. This language is called Sard.

Sard will re-implement a well-behaved subset of Scala on the Mono .NETvirtual machine. The .NET platform was chosen due to it’s very well main-tained virtual machines as well as having some features that Java lacks. Aneffort will be made to reduce dependence on .NET, so that the option of hav-ing other implementations on per example LLVM remains open. This will alsoensure that .NET-isms like null pointers and single inheritance do not make itinto the language.

The goal of this bachelor’s degree is to identify the exact subset to imple-ment, and to create a specification for it. This specification should at a veryminimum contain the following:

– An acceptation or rejection of every Scala feature, with a cogent motiva-tion for why/why not it should be in the language.

– A complete grammar/syntax for the language.

– A fully specified type system with sound semantics.

In order to meet these goals, I have consulted the literature on Scala, pon-dered what to leave in and what to remove, and discussed these decisions withmy supervisor. I have also held two seminars on this subset of Scala, andincorporated some of the feedback given.

Unfortunately, a bachelor’s degree does not provide sufficient time to im-plement and debug a compiler. Therefore, this exam will not concern itselfwith the implementation of this specification. I also wish to receive feedbackon what I will implement before much code has been written. This will makeit easier to change the specification, should the need arise.

In the future, I intend to write a compiler for this language in Haskell. Butthis will have to wait for the moment.

Page 12: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

4 Chapter 1. Introduction

Page 13: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

Chapter 2

Feature Set

In this chapter, every feature of Scala will be accepted or rejected, with a shortdescription of the feature and motivation of why it should/should not be in thelanguage. To save the time of the author and reader, any feature present inJava may be assumed to be present unless explicitly mentioned otherwise. Anycode examples will be illustrated with Scala, and thus some grasp of Scala’sbasic syntax will be needed to understand this chapter. For further reading onhow Scala works, I’ll refer you to the excellent O’Reilly book on Scala, whichis freely available online.[11]

2.1 Type Inference

In Scala, any type signatures in an expression context (i.e. on fields and insidemethods) are optional. If not specified, the compiler will infer types for yourexpressions. This is one of the greatest accomplishments of the ML familyof languages, enabling one to drastically cut down on the amount of unneededtyping, while at the same time keeping the safety and efficiency of static typing.As such, not including this in Sard would be a crime.

2.2 Trait Inheritance

Traits may be viewed as a compromise between full multiple inheritance andJava’s single inheritance with interfaces. A trait is basically a interface, butmay contain concrete methods, concrete and abstract fields, as well as typemembers (more on that later). The only thing that can be in a class thatcannot also be in a trait is a constructor.

5

Page 14: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

6 Chapter 2. Feature Set

1 //A d r a s t i c a l l y s imp l i f i e d ver s ion o f the I t e r a t o r t r a i t in Scala .trait I t e r a t o r [A] {

3 def hasNext : Booleandef next :A

5def map( f :A => B) : I t e r a t o r [B] = {

7 val s e l f = thisnew I t e r a t o r [B] {

9 def hasNext = s e l f . hasNext

11 def next :B = f ( s e l f . next )}

13 }}

In this example we can see approximately how the Iterator pattern is im-plemented in Scala. It is implemented as a trait with two methods next andhasNext. Using these two abstract methods, a variety of concrete methods canbe constructed. These will be available to subtypes of Iterator with no extrawork. In languages like C# or Java, there is no way to inherit concrete methodsfrom multiple sources. Hence, their Iterator interfaces generally just implementnext and hasNext, since it would be too odious for implementers of Iteratorto define various advanced operations like map. In Scala, there is no suchtension between thin-but-easy-to-implement and feature-rich-but-cumbersomeinterfaces. Implementing the Iterator trait is a matter of defining two methods,and yet that means one can get 10+ other methods defined for free.

Given the above, I consider it a given that traits have to be in Sard. How-ever, there are two ways in which it has been changed relative to Scala; Inher-itance is now symmetric and single inheritance has been removed.

2.2.1 Symmetric Inheritance

When one is able to inherit methods from multiple sources, one is faced with theproblem of what to do when two identical methods are inherited from multiplesources. In Scala, this is solved by the last-inherited method silently overridingthe others. This way of resolving conflicts is called linearization. In most cases,conflicts like this are rare, but when they occur, I want it to be an error, nota silent override. On occurrence of the error, the programmer can then takesteps to resolve it.

2.2.2 Removal of Single Inheritance

Single inheritance from a concrete class is already avoided by convention inOO languages. This is because the binding between parent and child classesbecome too strong, making the class hierarchy brittle in the face of changingrequirements, and making refactoring harder. In addition, we already havetrait inheritance in Sard, which is much more expressive.

Page 15: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

2.3. Compound Types 7

That means that in Sard, it is only possible to inherit from traits. Classeswhich are possible to instantiate are all considered final.

2.3 Compound Types

Since Sard has trait inheritance, it is possible to subtype multiple interestingtypes. Therefore, we need a syntactic way of expressing multiple subtyping.

trait Hashable {2 def hash : UInt

}4

trait Equal i ty [A] {6 def equa l s ( that :A) : Bool

}8

def f oo [A <: Equal i ty [A] with Hashable ] ( x :A) : Unit

In the above example, A in foo is a parametric type that is a subtype toboth Equality[A] and Hashable. This is very simple to implement, as the typesystem must already track multiple subtyping anyway. Also, it makes it easierto have many small traits, and only depend on mixes of them instead of concretetypes. This leads to more loosely coupled and expressive code.

2.4 Subclassable Closures

Scala, being a object-functional language, has a form of closures. A closure isa form of first-class function that can access variables defined in lexical scopefrom where the closure is defined. Being a first-class function of course meansthat functions in Scala can be bound to variables, created at runtime andreturned from other functions. This enables one to create so-called higherorder functions, which may be familiar if one has previous experience withfunctional languages.

Higher order functions are functions that take parameters that are them-selves functions. For example, there is a well known function called filter that,given a closure that takes a list element and returns a bool, selects the elementsfrom a list for which the closure returns true.

That describes closures in general. Scala’s closures in particular are alsoobjects. That is, there is a trait which makes the inheriting object a closure.If one inherits from one of the FunctionN types, the inheriting object will bea function of N input parameters. For example, an object subclassing Func-tion2[A,B,C] will be a function that takes two parameters of type A and B andreturns a type C.

Page 16: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

8 Chapter 2. Feature Set

1 def i sEven (x : Int ) : Boolean = x % 2 == 0(1 to 10) . f i l t e r ( isEven ) . t oL i s t // re turns L i s t (2 ,4 ,6 ,8 ,10)

3 // Like above , excep t t ha t we crea ted isEven on the f l y .(1 to 10) . f i l t e r ( x => x % 2 == 0) . t oL i s t

5var nrElements : Int = 0

7 (1 to 10) . f o r each ( ( x ) => nrElements = nrElements + 1)nrElements == 10 // true

9/∗

11 This i s how c l o su r e s with one parameter are de f ined .Any ins tance o f t h i s type can be invoked with the syntax

13 ” ins tance (a )” in s t ead o f ” ins tance . app ly (a ) ” .∗/

15 trait Function1 [+A,+B] {def apply ( a :A) :B

17 }

19 /∗A Function1 su b c l a s s where one can ask i f the func t i on

21 i s de f ined fo r t h i s va lue .For example , an Array i s a Par t ia lFunct ion [ Int , Element ] .

23 ∗/trait Part ia lFunct i on [+A,+B] extends Function1 [A,B] {

25 def i sDe f inedAt ( a :A) : Boolean}

Closures in general enable one to do vastly more with less code. Considerfor example filter. Every time a Java programmer wants to select a part of a listthat conforms to some condition, they have to do it manually with a for-eachloop that constructs a new list. In Scala, on the other hand, one can factor outthat pattern into a method, and then simply invoke it with a closure that givesthe condition. To this, Scala also adds the ability of any object to be a closure,and the possibility of specializing closures that perform something special, likethe PartialFunction example above. In summary, this is an enormous positive,and will definitely be in Sard.

2.5 Underscore Closures

A form of syntactical sugar for closures, in which underscores are used to anony-mously use the variables of the closure. This is best illustrated with an example.

// e qu i v a l en t to prev ious d e f i n i t i o n s2 (1 to 10) . f i l t e r ( % 2 == 0) . t oL i s t

val i sEven = % 2 == 0 // means ”x => x % 2 == 0”

Besides being a shorter syntax for closures, underscore closures can also beused for partial application. That is, the practice of only applying a closure tosome of it’s parameters, thus defining a new function.

Page 17: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

2.6. Tuples 9

1 def isMod (x : Int , div : Int ) : Boolean = x % div == 0/∗

3 Par t i a l a pp l i c a t i on o f isMod tha tchecks d i v i s i b i l i t y with two .

5 ∗/val i sEven = isMod ( , 2 )

While having a shorter syntax for closures is somewhat useful, the greatermotivation for keeping underscore closures is the partial application. This issomewhat of a core concept in functional programming, and one that againsaves lines of code.

2.6 Tuples

Tuples, as seen in many languages lately, are general pairs/triples e.t.c. ofvalues. These are a necessity to return multiple values from methods. It isnot an option to write a new sort of container object every time one wants toreturn two or more values from a method!

In Scala and Sard, tuples are instances of the TupleN types.

trait Product2 [+A,+B] {2 val 1 :A

val 2 :B4 }

6 class Tuple2 [+A,+B] ( a :A, b :B) with Product2 (a , b )

8 trait Product3 [+A,+B,+C] with Product2 [A,B] {val 3 :C

10 }

12 class Tuple3 [+A,+B,+C] ( a :A, b :B, c :C) with Product3 (a , b , c )

14 // And so on . .

16 val aPair : Tuple2 [ Int , Int ] = (5 , 2 )

Sard defines the tuple types and tuple expressions as shorthand for theappropriate version of TupleN.

2.7 Reified Generics

One unfortunate influence of Java on Scala is that generics are not saved atruntime. This makes any type of reflection involving type parameters unneces-sarily difficult. Fortunately, Sard rectifies this by implementing itself on .NET,which does save type parameters. As we will see in the next section, this makessome parts of Sard design much easier.

Page 18: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

10 Chapter 2. Feature Set

2.8 Type Members

A type member in Scala is a slot in an object which, instead of a field or method,contains a generic type parameter. Much like any slot, it can be concrete (i.ebound to an existing type, like Int, or another type parameter) or abstract, leftunspecified.

trait AbsCell {2 type T

val c e l l :T4 }

6 class I n tCe l l (var c e l l : Int ) extends AbsCell {type T = Int

8 }

10 val t e s t : AbsCell = new I n tCe l l (10)t e s t . c e l l // 10

12 t e s t . c e l l = 12

Some might ask what, if anything, this adds to the existing ways to havegenerics. One of these things is that, as mentioned above, types can be abstractand then specified in subclasses. Another is that type members can be limitedwithout being specified.

trait NumericCell extends AbsCell {2 type T <: Numeric

}

Taken together, this means that type members are much better suited thangenerics to when you have a hierarchy of types and one or more of the base typeshave generic parameters. If one wishes to inherit a type without specifying it,one must make it a parameter to the subclass as well, and so one for howevermany steps one must inherit it.

1 /∗With parameter ized types . ∗/trait Base [T <: Numeric [T ] ]

3 trait Type1 [T <: Numeric [T ] ] extends Base [T]trait Type2 [T <: Numeric [T ] ] extends Type1 [T]

5 trait Type3 extends Type2 [ Int ]

7 /∗With type members∗/trait Base {type T <: Numeric ;}

9 trait Type1 extends Basetrait Type2 extends Type1

11 trait Type3 extends Type2 {type T = Int ;}

That’s not to say that type parameters have no place however. For typemembers are not accessible in subtyping checks. They don’t count for subtypingpurposes, and if one wishes them to do so, they must be parameters.

Page 19: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

2.9. ML-Like Pattern Matching 11

2.9 ML-Like Pattern Matching

Another feature Scala borrows from ML is pattern matching. What patternmatching in Scala provides is a fast way of deconstructing an object. Patternmatching is essentially a quick way of selecting fields from an object, if thatobject satisfies an expression.

1 /∗This i s a case c l a s s h ierarchy .

3 An Option can be e i t h e r a va lueSome , or l a c k o f value , None .

5 ∗/abstract class Option [A]

7 case class Some [A] ( val some :A) extends Option [A]case object None extends Option [ Nothing ]

9val opt ion : Option [ Int ] = new Some (5)

11 /∗This i s a match expre s s ion . I t t r i e s to match

13 opt ion to one o f t he se pa t t e rn s .The va lue o f t h i s expres s ion i s t ha t o f the matching pa t t e rn .

15 I f no expres s ion matches , an excep t ion i s thrown .∗/

17 opt ion match {case Some [ Int ] ( 5 ) => −5

19 case Some [ Int ] ( x ) => xcase None => 0

21 }

The astute reader may have noticed that nothing about pattern matchingcan’t be done with if-else and type checks. However, the resulting code wouldbe much longer and more verbose. Observe:

1 // This i s e qu i v a l en t to the match expres s ion above .i f ( opt ion . isA [ Some [ Int ] ] {

3 i f ( opt ion . asA [ Some [ Int ] ] . some == 5) {−5

5 } else opt ion . asA [ Some [ Int ] ] . some} else {

7 0}

You may notice that, although pattern matching is exactly equivalent todoing a series of if’s with type checks, the if-else code is twice as long. Sincethis type of operation is rather common, it makes sense to have a fast way ofcompleting it. In conclusion, it should be kept in Sard.

However, there is a somewhat idiosyncratic detail about Scala’s patternmatching, namely that it only works on objects specified in advance. Youmay have noticed that we declared Option[A] in the last example to be a caseclass. This tells the Scala compiler that it should save the type and genericparameters of the object so that it can be pattern matched against. Doing sois a necessity on the JVM, where generics are not normally saved at runtime.

Page 20: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

12 Chapter 2. Feature Set

Due to the fact that Sard is not similarly constrained, we can generalize thatto any slot of any object.

This is Sard’s pattern matching:

sealed trait Option [A]2 class Some [A] ( val some :A) with Option [A]

object None with Option [ Nothing ]4

val opt ion : Option [ Int ] = Some (5)6 match( opt ion ) {

case Some [ Int ] ( some=5) => −58 case Some [ Int ] ( some=x) => x

case None => 010 }

You may notice that the ”case classes” of the past have now become justregular classes. You may also notice that the patterns indicate what slot theyare matching on. This is because unlike Scala’s pattern matching we can matchon any slot of any object, not just the construction parameters of a case class.

And when I say any slot, I mean literally any slot. For example, methods.

val hash f ind : Int => St r ing =2 match(HashMap [ Int , S t r ing ] ( ( 1 , ”one” ) , ( 2 , ”two” ) , ( 3 , ” three ” ) ) ) {

case HashMap( get=hashf ind ) => hash f ind4 }

hash f ind (2 ) // ”two”

There is also a special pattern for tuples.

1 val (x , y ) : ( Int , Int ) = (3 , 3 )

3 // De−sugared ver s ion o f the above .val tmp : Tuple2 [ Int , Int ] = Tuple2 [ Int , Int ] ( 3 , 3 )

5 val x : Int = match(tmp) {case Tuple2 ( 1=x) => x ;}val y : Int = match(tmp) {case Tuple2 ( 2=y) => y ;}

As previously mentioned in the tuple section, this is only a shorthand for aTupleN pattern. A tuple pattern with only identifiers is also the only kind ofpattern which can show up in a variable declaration. The idea being that onecan quickly bind the result of a returned tuple.

We may even, for completeness sake, pattern match on type members, al-though there is not much one can do with them.

trait Example{type T;}2 val t : Type = match(Example{T = Str ing ; } ) {

case Example (T=x) => x4 }

t . show // ” S t r ing ”

Page 21: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

2.10. Null Pointers 13

2.10 Null Pointers

Null or uninitialized pointers are one of the leading causes of errors worldwide.They are the billion dollar mistake.[3] One of the most important design goalsof Sard is to make this type of error impossible. In practice, this turns out tobe surprisingly easy.

The first step is to force all variables and fields to be initialized on creation.When declaring a variable/field, one must set it to a value immediately. Thissolves the problem for variables. But what if the object in which the fieldis created has multiple constructors? Or what if the field is to be abstract?The answer to the second question is that not initializing a field is leaving itabstract, and is used instead of an ”abstract” keyword on fields. The answerto the first one is a bit more complex.

In Scala and Sard, there is a ”main” constructor which consists of the classbody. The formal parameters to this main constructors are given after the classname.

1 class Example ( foo : Int ) {pub l i c val bar : Int = foo

3 }

Since one must initialize fields on creation or leave them abstract, this meansthat any object created with the main constructor is fully initialized. Now wecan solve the problem of adding more constructors.

Since any object constructed with the main constructor is fully initialized,the problem can be solved if we could guarantee that all constructors called themain one. We can do this by forcing every constructor’s first statement to be acall to a constructor that has already been defined. Since the main constructoris defined first, every constructor call goes through it eventually. And so allobjects are fully initialized.

Thus having guaranteed reference safety in Sard, the problem facing us nowis how to model a value that can possibly be missing? For this, the Option[A]type we introduced earlier does the trick. Using that, we can easily model thelack of value as None.

I can take no credit for any of the above. All of these solutions are alreadyimplemented in Scala. However, due to being constrained by Java backwardscompatibility, they need the null pointer to be able to pass nulls in and outof Java methods. Remove the need for Java compatibility, and removing itbecomes just a matter of removing the null literal.

2.11 Syntactic Sugar for Constructors

There is a rather simple bit of syntactic sugar in Scala for object construction.It defines a shortcut for when the main constructor of an object directly savesa constructor parameter as a field.

Page 22: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

14 Chapter 2. Feature Set

1 class Example ( pub l i c val f oo : S t r ing )new Example ( ”He l lo ” ) . foo // ”He l lo ”

Note in the above example foo is both the name of the formal parameter andof the field it sets. Doing this eliminates having to come up with a temporaryname for a constructor parameter when one is just saving it in a field anyway.This is a common case, and as such should be optimized. Conclusion: Keep.

2.12 All statements return a value

One of the better features of ML that Scala borrows is the notion that every-thing has or returns a value. In Scala, all statements return a value. If thestatement in question is one that works entirely through side effects, the specialvalue ”Unit” is returned. The Unit can be considered a sort of sentinel valueindicating that the statement produced no (useful) value.

The if-statement returns the value produced by the branch taken. Hence,the true- and false-branch of the if-statement must have the same type, and asingle-branch-if must have type unit.

val x = i f (−1 < 0) −1 else 1 // Binds x to −1.2

/∗4 I l l e g a l ! The branches o f t h i s i f have

d i f f e r e n t types ( In t and Unit ) .6 ∗/

i f (−1 < 0) 1 else p r i n t l n ( ” p o s i t i v e ” )8

// Fix o f the above .10 val y =

i f (−1 < 0) {12 1

} else {14 p r i n t l n ( ” p o s i t i v e ” )

116 }

As you may have noticed in the last example, the fact that we printedsomething before returning 1 didn’t matter. That’s because blocks too have avalue, and that’s the value of the last statement they execute. Since the laststatement above is an Int, the block has type Int, and this typechecks.

Finally, try-catch-finally also has a value. That’s the value of it’s try- orcatch block. Hence, the try and catch blocks must again have the same type,and the finally block must have type unit.

Page 23: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

2.13. Default Values for Parameters 15

val exitCode =2 try {

val f i l e = openFi l e ( ” foo . txt ” )4 f i l e . f p r i n t l n ( ”Foo” )

06 } catch {

/∗8 Exception in Scala i s a pa t t e rn matching .

Any excep t ion not matched i s thrown f u r t h e r .10 As per a l l pa t t e rn matching , one can have a

d e f a u l t case t ha t matches anything .12 ∗/

case FileNotFound => 114 case Permiss ionError => 2

}

2.13 Default Values for Parameters

Default values are, as the name implies, a way to specify a default value fora method parameter. This parameter can then be left out of the methodinvocation, in which case it will receive it’s default value.

1 def add ( arg : Int , amt : Int = 1) : Int = arg + amtadd (0) // 1

3 add (1 , 2 ) // 3

This is occasionally useful when there are more than one default parameter.When there is just one, one may just as easily replace it with two methods, onewhich gives default values to the other. When there are three or more defaultvalues however, this gets ugly fast. I’m therefore leaning towards keeping them,although it is not a very important issue either way.

2.14 Method Overloading

As the reader surely knows, this is the practice of having several methods withidentical names in the same class. If they then have different types, the compilercan decide which method to invoke for any given object.

However, there is nothing to stop one from simply giving the overloadedmethods different names. Very little of value would be lost doing that instead.In addition, method overloading complicates the implementation of some otherfeatures, like type inference. Therefore, this will not be possible in Sard.

2.15 Companion Objects

Scala does not have static members. What it has instead is a feature wherebya static class (”object” declaration in Scala) can share namespace with a class.

Page 24: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

16 Chapter 2. Feature Set

1 class Fooobject Foo

So if you define a class and and an object, in the same file, with the samename, they have the same namespace. This is more or less semantically iden-tical to having static members.

I decided to keep them, as we still need some way of representing staticfunctions that belong to a class. It’s a pattern that comes up quite often.

2.16 Infix Syntax for Methods

In Scala, methods with only one parameter can be written in infix syntax.

class Example extends Int {2 def mod(d : Int ) = this % d

}4 new Example (5 ) mod 3

new Example (5 ) .mod(3) // what the above l i n e means

Scala uses this to implement operator overloading. Basically, one can useany ASCII symbols in a method name, so + is just a one-argument methodlike any other. Instead of writing ”x + y”, one could write ”x.+(y)” and itwould have the same semantics.

Personally, I’m not a fan of this decision, for it means one can do two thingswhich are wholly unnecessary:

1. Invent new operators like -*-, the meaning of which can only be guessedat.

2. Call regularly named methods in infix or regular postfix syntax.

It’s a well established practice to name things in a somewhat informativeway. However, there is no series of English phrases that is as uninformative asa series of ASCII punctuation symbols. The only time when an operator is thebest variable name is when dealing with mathematics and comparison. For inthe case of symbols like + and !=, they actually have a known meaning.

Neither is there much point to having two method call syntaxes. Why notjust one? They are semantically identical anyway, so why complicate matters?

Due to the above issues, I’m removing infix syntax from Sard, as well as theability to have anything other than ASCII letters and underscores in methodnames.

This does remove the ability to overload the numerical and comparisonoperators. To reintroduce that functionality, I’m bringing a somewhat C#-likeway of overloading operators.

In Sard, there are some primitive traits that have operators defined on them.For example this one:

Page 25: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

2.17. Structural Subtyping 17

1 trait Equal i ty [A] {def equa l s ( that :A) : Bool

3 }

Anything that implements this trait and defines equals, one can use the== and != operators against. The numerical traits are similarly defined a intrait called Numeric[A]. In all cases, the basic pattern is that operators can’tbe created or overloaded directly. One can however mix in a trait that definesoperators in terms of some methods. Methods which one may implement. Thishas the advantage that the useful and well-behaved overloading of numericaloperators remains, whereas operators named *!!* do not.

2.17 Structural Subtyping

In most statically typed OO languages, subtyping is always nominative. Thatis, a type A is considered a subtype of type B if and only if the programmerexplicitly says it is. This is what ”extends” in languages like Java means.One is declaring this type to be a subtype of the supertype. There is howeveranother way of doing subtyping, found in O’Caml and Python, where subtypingis structural.

What this means is that we consider that A is a subtype of B iff A has allthe methods that B has. If B has one method with the signature def foo:Unit,then any object with a method named foo that takes and returns no valuewould be considered a B.

Having structural subtyping alone presents a number of problems. Themost thorny one being that the pattern in nominatively typed languages whereone defines required functionality in an abstract superclass or trait, and thenrelies on subclasses to still have that functionality would be impossible. Tokeep with my A and B example, just because A has a method foo, that doesnot mean it does what a B expects it to do. Perhaps I defined B.foo to be asealed method which logs something, whereas A.foo does something completelydifferent. In summary, if one had structural subtyping only, using subtypingto guarantee some behavior would no longer work.

The path that Scala took is to instead have both structural and nominativesubtyping. A somewhat recurring pattern in Scala’s design is that, when facedwith a decision between two things, they elect to pick both. For some things,like calling strategies, this approach worked well enough. However, I wouldargue that having two ways to implement subtyping is a bit gratuitous. Mostlybecause both subtyping strategies overlap to a rather large degree. Structuralsubtyping can use trait-like functionality without defining traits (by defining arequired structure for parameters to methods) and nominative subtyping canguarantee invariants by subtyping. But the benefits of having both are, in myhumble opinion, too slim to motivate the complexity of doing so. I knew prettyearly on when starting Sard that I wanted to remove one of the subtyping

Page 26: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

18 Chapter 2. Feature Set

strategies, and eventually elected to remove structural subtyping, due to theaforementioned benefit of nominative subtyping.

2.18 Call-by-value, -by-need and -by-name

The three most common ways of passing parameters to a method are call-by-value, call-by-need and call-by-name. Scala implements all of them. By-name isthe most common behavior, and so is the default. In this variant, parametersare fully evaluated before being passed to methods, and the resulting valueis copied into the method. In by-name, the formal parameter is effectivelyreplaced by the bound expression. Which effectively means the parameter isnot evaluated on call, and is evaluated once per every time it is used in themethod. By-Need is much like By-Need, except it is only evaluated once, thefirst time it is used.

In Scala, as previously mentioned, by-name is the default, since that is whatthe JVM does. This is good, most code is after all strictly evaluated. The othertwo are implemented by closures. By-Name is a no-argument closure, whoseexpression is the one the formal parameter is set to. Whenever the formalparameter is mentioned, the closure is called. By-Need, in a supremely elegantimplementation, is a subtype of a no-argument closure that saves it’s result thefirst time it’s called, and is thereafter not evaluated again.

I’m all in favor of keeping this feature, partly because it’s very elegance,but also because implementing lazy evaluation over a strict host language isotherwise very difficult.

2.19 Module and Import System

In Sard, one can switch between imports being relative (from the current folder)and absolute (from the core library folder), depending on whether one prefixesthe classpath with ”sard.” or not.

Unlike Scala, there is no concept of a package except as a folder. That is,a class shares a package with all classes in the same folder, and that’s the onlyway to specify packages.

Another thing that’s been simplified from Scala is that the ability to renameclasses when importing them is removed. Instead, one can stick to using path-qualification in the few instances where it’s necessary.

In Sard and Scala both, one can import multiple or all classes from a pack-age, like so:

1 /∗Abso lute import with a s e t . ∗/import sard . c o l l e c t i o n .{ List , Set }

3 /∗Abso lute import with a wi ldcard . ∗/import sard . i o .

5 /∗Re la t i v e import with one c l a s s . ∗/import mymodule . Example

Page 27: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

2.20. VarArgs 19

2.20 VarArgs

In Scala and Sard both it’s possible to have a variable number of arguments tomethods and constructors. There may only be one variable argument at theend. The variable arguments are packed into an Array.

def sum( i n t s : Int ∗) : Int = i n t s . sum2

sum(1 , 2 , 3 , 4 , 5 ) // 15

This is highly useful because constructors with variable arguments can beused instead of collection literals. E.g ”List(1,2,3)” is just a constructor callwith 3 arguments. If VarArgs where removed, one would have to replace themwith some other form of collection literal. Therefore, it appears that they holdan important role in Sard.

2.21 Local Methods

In Scala, it’s possible to have local methods. I.e. methods defined solely withinanother method. They are of course easily replaceable with private methodsdefined at the same level as the parent method. Also, the potential complex-ity of having every method potentially be a module makes implementing thecompiler unnecessarily difficult. Therefore, I’m going to remove them.

2.22 For-Each Loops and Enumerations

Both for-each loops and enumerations are very familiar to OO programmerseverywhere. They are also, in a language like Scala, completely unnecessary.The for-each loop is basically a very simple closure, and the enumeration is avery simple sealed class hierarchy. I see little point to having multiple ways ofdoing the same thing.

2.23 XML-Literals

Scala has a number of features which are, on balance, more of a negative than apositive. But XML-literals is the only one which genuinely lacks merit. As thename implies, this is a way of writing literate XML inside Scala code. Thereare two major problems with this:

1. This is better solved with libraries.

2. XML!

First and most importantly, high-level tasks like serialization to text arebetter handled by libraries. There is no reason, no reason at all, why XMLreading/writing couldn’t have been implemented in a library. On the otherhand, there are a number of reasons why it should have been done that way.

Page 28: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

20 Chapter 2. Feature Set

1. One can switch to different XML libraries.

2. One can switch serialization formats more easily.

3. The language is not tied to any one specific serialization format.

4. XML is not any more special than any other data format. Why makethis primitive instead of {JSON,Markdown,CSV}?

On the other hand, XML-literals may make it easier to work with XML. Butthis was not a problem that needed solving. XML is one of many serializationformats. And I for one would pick each and every one of them ahead of XML.Up to and including rolling my own plaintext format. Why? This matter hasbeen debated to death already, so I’ll just refer to several excellent texts onwhy XML, to paraphrase Dijkstra, ”should be considered harmful”.[1][2]

2.24 Tail-Call Optimization

Sard is an at least half functional language. As such, many loops will bereplaced with recursion. To make sure that it is possible to recurse indefinitely,tail call optimization is necessary. Tail call optimization is, as you may know,an optimization which makes sure that no function call that ends on anotherfunction call consumes stack space. As such, one can recurse forever instead ofjust until the call stack is full. Fortunately, TCO is already present in .NET,so no additional work from me is necessary.

2.25 Annotations

Annotations are a sort of ”first-class comment”. That is, a special type ofcomment which is actually stored on the object/method in question, and in-spectable by meta-programming.

One can, per example, use annotations to indicate that an object is serial-izable, or unboxed, or a number of other things. The problem with all of themis that they really aren’t compatible with static verification; None of these arechecked until runtime, and even then only by reflection. I would thereforeadvocate replacing annotations with regular documentation.

2.26 Uniform Access

An old problem in object orientation is how to replace a field with getter/settermethods. One often finds that a getter/setter must do something else besidesjust getting/setting the field. This could include logging, error checking or anynumber of things. Due to the inherent difficulty of doing this without rewritingall code using the object in question, some Java coders have taken to avoiding

Page 29: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

2.27. Symbols 21

public fields entirely, starting with getters/setters even in the trivial cases whenthey are not really needed.

Scala solves this problem in two ways: For accessors, field selection and call-ing a no-argument method looks exactly the same syntactically. For mutators,any method whose name ends with ’ =’ can be called like so:

1 class Foo {def f o o =(x : Int ) : Unit

3 }

5 // These two expre s s i ons are e qu i v a l en t .new Foo . foo = 5

7 new Foo . f o o =(5)

This means that there is no penalty to using public fields, as it is simple toreplace them with getters/setters later.

2.27 Symbols

A symbol is a interned string. What that means is that two symbols with thesame name will always refer to the same object.

1 val exampleMap = new HashMap [ Symbol , Int ]exampleMap += ( ’ one , 1 )

3 exampleMap += ( ’ two , 2 )exampleMap += ( ’ three , 3 )

5 exampleMap ( ’ two )

Symbols are mostly intended to be an alternative to String for map keys.Frankly, I see no reason why one couldn’t have stuck with strings instead.

2.28 Variance Annotations

Variance annotations are a way of specifying how type parameters behave w.r.t.subtyping. For example, if we have a type List[T], should List[String] be con-sidered a subtype of List[Any]? There are three kinds of variance: Covariant,contravariant and invariant.

In invariant subtyping, only the same type parameter is allowed. So only aList[T] is considered a subtype of List[T]. This is the behavior present in Java.In covariant subtyping, List[A] is a subtype of List[T] iff A is a subtype of T.In contravariant subtyping, it’s the other way around; List[A] is a subtype ofList[T] iff A is a supertype of T.

In Scala syntax, variance of a class type parameter is noted in the classheader like so:

1 class I nva r i an tL i s t [T]class Covar iantL i s t [+T]

3 class Contravar iantL i s t [−T]

Page 30: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

22 Chapter 2. Feature Set

Note that each type parameter of a class has it’s own variance behavior.So it is possible to combine covariance and contravariance if a class has severaltype parameters.

Control over variance is necessary in Sard, because in certain corner caseslack of control over variance can render code type-unsafe. Consider the belowexample:

1 val arr1 : Array [ S t r ing ] = Array ( ”Test ” )val arr2 : Array [Any ] = arr1

3 val e r r o r : Int = 5arr2 (1 ) = e r r o r // We j u s t added an Int to an Array [ S t r ing ] !

In order to prevent this sort of thing, Java’s design team decided thatall class type parameters should be invariant. A solution which can only bedescribed as gross overkill. Scala solved this much more elegantly by lettingthe programmer control variance.

2.29 Multi-Line Strings

In Scala, strings which begin with triple quotes can span multiple lines. Inorder to simplify this, I decided to instead just keep the regular single-quotestring, and let that one span multiple lines.

2.30 Named Arguments

One may invoke methods with named parameters in Scala, like so:

class Box( val width : Int , val he ight : Int )2 new Box( he ight=5,width=4)

This has some marginal utility to catch argument transposition bugs; Thatis, when one orders similarly-typed arguments wrong, like exchanging widthand height in the example above. However, I find that to use this, one mustconsult documentation or source to find the argument names, at which pointone knows their position already. And of course, using named arguments isoptional, so one is still quite capable of transposing one’s arguments in spite ofthis existing. In summary, I’m slightly in disfavor of implementing this feature.

2.31 Optional Dynamic Typing

One of the more important reasons I decided to create Sard is Scala’s recentintroduction of dynamic typing. As the reader may know, Java 7 arriving thissummer is introducing dynamic (non-type-checked) types. Since Scala has tomaintain calling compatibility with Java, they have already introduced theminto the language.

Page 31: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

2.32. Casting 23

There are two main reasons this is a bad idea. The first being that nearly alloptimizations depend on the ability of the compiler to know what type objectshave. Remove that, and performance drops by an order of a magnitude. Onlya few optimizations can be applied dynamically at runtime; And furthermorethey all share the characteristic that they can be applied just as easily in staticlanguages.

While this is certainly bad enough, the more important problem is thatdynamic typing implies more buggy programs. In static typing, one has theability to detect bugs automatically. There are no convincing arguments onwhy one would not want that. None whatsoever.

I believe that dynamic typing has sprung up mostly as a reaction to Java’s(very poorly designed and inexpressive) type system. A properly designed typesystem found in languages like Haskell, ML or Scala is simply a better choicecompared to type-unsafe alternatives.

2.32 Casting

As a consequence of having pattern matching, it is possible to remove type-casting in Sard. It is desirable to do so because typecasts introduce a quitesignificant element of type-unsafety whenever they are used. If the cast is im-possible, the program will throw an exception a runtime. Being a type-safelanguage, Sard should always strive to move errors as far away from runtimeas possible; It is much better to get an informative error message with linenumbers at compilation, rather than a cryptic exception when the program isrun.

So how do we replace casting? The solution is two-part: One for casts to asupertype, one for a cast to a subtype.

For casts to subtype, pattern matching can be used to match the currenttype of the object. The first matching case will be picked. The advantage overcasting is that one has more precise control over failure than with casts, andone can check for multiple types at the same time. Pattern matching is alsomore easily statically verified.

For casting to supertype, one can simply assign the object in question to areference of the appropriate type.

2.33 Existential Types

An existential type is much like a generic type parameter, except that it is notbound to a name. What does this mean? Observe:

/∗Type o f r eve r s e method wi thout e x i s t e n t i a l type . ∗/2 def r e v e r s e [B ] ( xs : L i s t [B ] ) : L i s t [B]

/∗Type o f r eve r s e method with e x i s t e n t i a l type . ∗/4 def r e v e r s e ( xs : L i s t [ ] ) : L i s t [ ]

Page 32: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

24 Chapter 2. Feature Set

The difference between the two is that in the first method, the element typeof the list is bound to a name - B. In that method, you can then define variablesof type B. If B had some known supertype, you could invoke methods on B’stoo. An existential type however is not bound to a name, and so can’t bemanipulated in any such interesting ways. It is mostly useful when the type inquestion is irrelevant, and one simply wishes to ”throw it away”. However, anyexistential type can, as the above example shows, be replaced with a regulartype parameter. This leads me to believe that there is little benefit to be hadkeeping them.

2.34 Self-Type Annotations

In most other object-oriented languages, the type of ”this” inside any classis always the same as the enclosing type. However, eliminating this need isactually both possible and type safe. And doing so can reduce dependencies incode, making for a convenient way of doing dependency injection. Basically, aself-type annotation means that a concrete subclass of this (abstract) class hasto subtype the annotation type. This is best explained by example.

trait A2 trait B extends A

/∗A t r a i t , wi th a s e l f−type annotat ion tha t r e qu i r e s A./4 t r a i t C { s e l f :A => }

/∗We j u s t mixed B in to C wi thout ever mentioning B in C. ∗/6 t r a i t D extends C with B

By doing the above, you can see that self-type annotations enable you toleave some subtyping abstract, thus defining the exact inheritances later. How-ever, this concept has a considerable overlap with abstract inheritance, to thepoint that it’s diff

2.35 Higher-Kinded Generics

Most modern statically typed languages have generics. Scala however also hasgenerics of a higher kind; One whose generic parameters can themselves haveparameters.

class Type [A[B ] ]

The above is a legal type in Scala, and means that the class Type takes onetype parameter A, which itself must have one type parameter B. Using thisweird and wonderful feature it is possible to define traits like this one:

Page 33: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

2.36. Implicit Parameters and Conversions 25

1 /∗This t r a i t t ake s a func t i on o f A to B,

3 and turns i t in to a Function from F[A] to F[B]f o r any type F.

5 ∗/trait Functor [F [A ] ] {

7 def fmap [B] ( f :A => B) :F [B]}

9// This i s an ins tance o f a Functor where F == Li s t and fmap ==

map.11 trait L i s t [+Elem ] with Functor [ L i s t [ Elem ] ] {

def fmap [B] ( f :A => B) : L i s t [B] = this .map( f )13 }

The above example simply cannot be written in languages without higher-kinded generics. A type system with them is strictly more powerful than onewithout. And so they will still be in Sard.

2.36 Implicit Parameters and Conversions

After having struggled a bit with this, I feel that I can’t explain how implicitparameters work; Not that I don’t know how they work, I just cannot cogentlyexplain how they work without mentioning Haskell’s type classes, an explana-tion that is unhelpful at best to the layman. If the reader does not already knowwhat implicit parameters are I’ll refer you to ”Programming Scala”, which doesa much better job of explaining them.[11] Martin Odersky also goes into quitesome depth discussing the correspondence with type classes in this paper.[5]

As for my views on implicit parameters: While I have programmed quite abit of Haskell, and was thus previously familiar with implicit parameters whenI saw them, I am nevertheless skeptical of their utility in Scala.

Type classes where originally introduced as a way of representing ad-hocpolymorphism in functional languages.[8] Hence a lot of the terminology aroundtype classes; The choice of terms like ”class” and ”instance” is not a coincidence- they where representing object-oriented programming! In a language likeSard, which already has a lot of ad-hoc polymorphism by other means, theutility of type classes is diminished.

Another point where this concept fits poorly into the OO paradigm is encap-sulation; Type classes are not encapsulated in any way, shape or form. Whenlooking up an implicit, the compiler looks in the following area:

1. Within lexical scope from calling site of method with implicit parameter.

2. Within lexical scope of definition site of the same method.

3. Within all superclasses of the object containing the call site.

4. Within all superclasses of the method definition site.

Page 34: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

26 Chapter 2. Feature Set

When one wants to answer what type classes are present at any point, theanswer is hard to come by without some kind of graph search algorithm! This isan important problem, as what implicit values are in scope affects the behaviorof the methods in question. Consider for example this method:

1 def map [B, That ] ( f :A => B) ( implicit bf : CanBuildFrom [ Repr ,B, That ] ) :That

This is the definition of map on Scala collections. What makes it unique isthat it uses an implicit, CanBuildFrom, to determine what collections can bebuilt from what source. This enables things like the following:

1 val s e t1 : Bi tSet = BitSet ( 1 , 2 , 3 , 4 , 5 )val s e t2 : Set [ S t r ing ] = se t1 .map( . t oS t r i ng )

We can build a Set[String] from a BitSet because somewhere there is aCanBuildFrom[BitSet,B,Set[B]] which indicates this is possible. But where isit? And how many more instances of CanBuildFrom are there at this point?Just what kinds of collections can be built from a BitSet anyway? To answerthese questions, we have to do the aforementioned graph search. This seemsto me an indication that implicit values break all semblance of encapsulatingbehavior.

The fact that theoretically this could be solved with documentation and/orbetter file organization is irrelevant. Everything becomes safe, provided oneworks hard enough at keeping it that way. There shouldn’t even be an oppor-tunity to have such a gratuitously large scope in the first place.

Page 35: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

Chapter 3

Syntax

In this chapter, I’ll present the Syntax of Sard and detail the changes of Sardrelative to Scala. I’ll assume that the reader is familiar with Scala’s existingsyntax, as well as Extended Backus-Naur Form notation for syntax.

3.1 Changes relative to Scala

There are a number of removed features of Scala, most of which affect theSyntax. They will not be specified again. There are also some minor changesto Scala’s syntax that were not accompanied by any features being removed.These will be discussed here.

3.1.1 New Closure Syntax

The syntax for creating and using closures have received several changes inSard. While Scala’s underscore closures remain unchanged, the regular closureshave a new syntax. Scala’s syntax is an argument list for the closure, followedby a left arrow, then an expression. Sard’s syntax is the keyword ”do”, andargument list, and an expression (no separator). The reason for the new syntaxis that it is easier to parse, and in my own opinion also easier to read.

Scala’s syntax:

(1 to 10) . f i l t e r ( x => i sEven (x ) )2 (1 to 10) . f i l t e r ( isEven ( ) )

(1 to 10) . f i l t e r ( ( x ) => { i sEven (x ) ; } )

Sard’s syntax:

1 Range (1 ,10 ) . f i l t e r (do( x ) isEven (x ) )Range (1 ,10 ) . f i l t e r ( isEven ( ) )

3 Range (1 ,10 ) . f i l t e r (do( x ) { i sEven (x ) ; } )

27

Page 36: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

28 Chapter 3. Syntax

3.1.2 The Removal Of ”new” Around Object Creation

In Sard, objects are not created using the ”new” Operator, like in Java orScala. Instead, one just applies the class name to parameters. This has beenchanged because Sard, like Scala, is a semi-functional language. As such, manyobject are immutable, and many objects are created instead of being modifiedin-place. So object creation must be syntactically short.

Scala’s syntax:

1 val map = new HashMap [ Str ing , Int ] ( 1 0 )

Sard’s syntax:

1 val map = HashMap [ Str ing , Int ] ( 1 0 )

This has the potential to become ambiguous if the class in question:

1. Has a companion object.

2. This companion object subclasses a FunctionN type.

3. This FunctionN type overlaps with one of the object’s constructors.

If all the above are true, then a dispatch becomes ambiguous. In thatcase, a compile-time error is generated. However, this is also an opportunity,in that constructors can transparently be replaced with factory methods on acompanion object.

3.2 Syntax Specification

In this section, the syntax of Sard will be listed and briefly discussed. Famil-iarity with Extended Backus-Naur form is a must.

1 (∗ The Syntax o f Sard ∗)

3(∗ Class Syntax ∗)

5 F i l e = [ HashBang ] { Import} FileMember ;

7 (∗ Present so that one may use shebang syntax in the fu tu r e . ∗)HashBang = ”#! ”{Unicode }”\n” ;

9(∗ Import Syntax . ∗ )

11 Import = ” import ” ModuleName Terminator ;ModuleName = { Id ” . ”} ( TypeId | WildCard | Set ) ;

13 Set = ”{”TypeId {” ,” TypeId}”}” ;

15 (∗A F i l e may conta in one top l e v e l c l a s s ,

17 po s s i b l y with a companion .∗)

19 FileMember =

Page 37: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

3.2. Syntax Specification 29

Object [ Tra i t | Class ] |21 Class [ Object ] |

Trai t [ Object ] ;23

(∗ The three d i f f e r e n t k inds o f types . ∗)25 Class =

” c l a s s ” TypeId [ Context ] [ ClassFormals ] I n h e r i t [ ClassBody ] ;27 Object = ” ob j e c t ” TypeId [ Context ] I n h e r i t [ ClassBody ] ;

Tra i t = [ ” s ea l ed ” ] ” t r a i t ” TypeId [ Context ] I n h e r i t [ ClassBody ] ;29

I nh e r i t = {”with” SimpleType} ;31 ClassFormals = ”(” ClassFormal {” ,” ClassFormal } [ ” ∗ ” ] ” ) ” ;

(∗33 D i f f e r s from a normal formal parameter in that one

can save i t as a f i e l d .35 ∗)

ClassFormal =37 [ [ ” ov e r r i d e ” ] [ V i s i b i l i t y ] [ ” s e a l ed ” ]

(” va l ” | ”var ”) ] Arg [”=” Expr ] ;39

(∗ The contents o f a c l a s s body . ∗)41 ClassBody = ”{”{ S lo t | Statement }”}” ;

S l o t = [ ” ove r r i d e ” ] [ V i s i b i l i t y ] [ ” s e a l ed ” ] ClassMember ;43 V i s i b i l i t y = ” pub l i c ” | ” protec ted ” | ” p r i va t e ” ;

ClassMember = Class | I n i t | TypeMember | Def ;45 I n i t = (” va l ” | ”var ”) ValuePat [ ” : ” Type ] [”=” Expr ] ;

In i tConc re t e = (” va l ” | ”var ”) ValuePat [ ” : ” Type ] ”=” Expr ;47 TypeMember = ” type” Re lat ion [”=” Type ] ;

Def = ” de f ” (DefReg | DefNew) ;49 DefReg =

Id [ ”=” ] [ Context ] [ Formals ] ” : ” Type ”=” BlockStatement ;51 DefNew = ” th i s ” [ Formals ] ”=” NewBlock ;

NewBlock = ConsCall | ”{” ConsCall {Statement} ”}” ;53 ConsCall = ” t h i s ” [ Actuals ] Terminator ;

Formals = ”(”Formal {” ,” Formal } [ Arg ”∗” ]” ) ” ;55 Formal = Arg [”=” Expr ] ;

Arg = Id ” :”Type ;57 BlockStatement = Block | Statement ;

Block = ”{” Statement{Statement }”}” ;59

61 (∗ Type Syntax ∗)

63 (∗ A Context d e f i n e s new type parameters in scope o f a method orc l a s s . ∗)

Context = ” [” VarRelat ion {” ,” VarRelat ion }” ]” ;65

(∗ A Limited type with a var iance annotat ion . ∗)67 VarRelat ion = [”+” | ”−”] Re lat ion ;

69 (∗ An ( op t i o na l l y bounded ) type va r i ab l e d e c l a r a t i on . ∗)Re lat ion = TypeId [ TypeArgs ] [ ”>:” Type ] [ ”<:” Type ] [ ” : ” Type ] ;

71(∗ A c lo su re , a r e gu l a r type or a lazy c l o s u r e . ∗)

73 Type =”(”Types ”) ” {”=>” AType} |

Page 38: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

30 Chapter 3. Syntax

75 CompountType |”=>” Type ;

77(∗ Present so one may chain Function types , e . g . A => B => C. ∗)

79 AType =”(”Types ”) ” {”=>” AType} |

81 CompountType ;

83 CompountType = TypeSe lect ion {”with” TypeSe lect ion } ;(∗ Syntax f o r s e l e c t i n g a type member i n s i d e a Context . ∗)

85 TypeSe lect ion = SimpleType{”#”TypeId} ;

87 (∗ A simple type that i s o p t i o na l l y path q u a l i f i e d . ∗)SimpleType = { Id ” .”}TypeId [ TypeArgs ] ;

89(∗

91 A Type name in Sard must s t a r t withan uppercase ASCII cha rac t e r .

93 ∗)TypeId = ASCIIUpper{ IdChar} ;

95 TypeArgs = ” [” Types ” ]” ;Types = Type {” ,” Type} ;

97

99 (∗ Express ion Syntax ∗)

101 Statement = Express ion Terminator ;(∗

103 A Statement cont inues un t i l the end o f thel i n e or un t i l a semico lon .

105 ∗)Terminator = ”\n” | ” ;” ;

107(∗ Grammar o f a l l e xp r e s s i on s . ∗)

109 Expr =PatternMatching |

111 MessageChain |In i tConc re t e |

113 Return |While |

115 Throw |Try |

117 Do |I f

119While = ”whi l e ” ”(”Expr ”) ” BlockStatement ;

121 Throw = ”throw” Expr ;Return = ” return ” [ Expr ] ;

123 Do = ”do” [ Formals ] BlockStatement ;Try =

125 ” try ” BlockStatement[ ” catch ” Cases ]

127 [ ” f i n a l l y BlockStatement ” ] ;I f = ” i f ” ”(”Expr ”) ” ( StatementI f | Block I f ) ;

129 StatementI f = NonTermStatement [ Terminator | Else ] ;B l o ck I f = Block [ El se ] ;

Page 39: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

3.2. Syntax Specification 31

131 Else = ” e l s e ” BlockStatement ;

133 (∗ Grammar f o r pattern matching exp r e s s i on s and a l l pa t t e rns . ∗)

135 (∗ A pattern matching exp r e s s i on . ∗)PatternMatching = ”match” ”(”Expr ”) ” Cases

137 Cases = ”{”Case{Case}”}” ;

139 (∗A s i n g l e case in a pattern match , with op t i ona l cond i t i on

141 f o r matching , as we l l as a BlockStatement to execute i f thematch succeeds .

143 ∗)Case = ” case ” Pat [ ” i f ” Expr ] ”=>” BlockStatement ;

145Pat = SimplePat [ ” as ” Id ] ;

147 (∗ SimplePat ’ s are those that are l e g a l to nes t i n s i d e a Pat . ∗)SimplePat =

149 Pr imi t ive |WildCard |

151 TuplePat |TypePat |

153 Id ;(∗ A ValuePat may be found in a I n i t or In i tConc re t e . ∗)

155 ValuePat = ”(” Id {” ,” Id }”) ” | Id ;(∗ Matches the appropr ia t e tup l e type . ∗)

157 TuplePat = ”(”Pat {” ,” Pat }”) ” ;(∗

159 A pattern that matches the i d e n t i f i e d type ,and i t ’ s named f i e l d s match the FieldPat ’ s .

161 ∗)TypePat = SimpleType [ ” ( ” Fie ldPat {” ,” Fie ldPat }”) ” ] ;

163 Fie ldPat = (TypeId | Id ) ”=” Pat ;(∗ Matches anything . ∗)

165 WildCard = ” ” ;

167(∗ A message chain with a source . ∗)

169 MessageChain = [UnaryOp ] Source {Actuals } [ S e l e c t i o n ](∗ The l e g a l ways to s t a r t a MessageChain . ∗)

171 Source =TypeId [ TypeArgs ] |

173 Pr imi t ive |WildCard |

175 Actuals |” super ” |

177 ” t h i s ” |Id ;

179 (∗Depending on the context may be a tup l e con s t ru c t i on

181 or the ac tua l parameters o f a func t i on c a l l .∗)

183 Actuals = ” ( ” [ Expr {” ,” Expr } ] ” ) ” ;

185 (∗A s e r i e s o f type or i d e n t i f i e r s e l e c t i o n s ,

Page 40: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

32 Chapter 3. Syntax

187 each one po s s i b l y with parameters .Ended with an ExprTail .

189 ∗)S e l e c t i o n = {” . ” ( Id | TypeId [ TypeArgs ] ) {Actuals }} [ ExprTail ] ;

191(∗

193 Binary operator expre s s i on s ,a c l a s s i n i t i a l i z a t i o n ,

195 e x p l i c i t type annotat ions ,s e t t i n g o f a va r i ab l e .

197 ∗)ExprTail =

199 {BinaryOp Se l e c t i o n } |ClassBody |

201 ” :” Type |”=” Expr ;

203(∗ Sard ’ s p r im i t i v e types . ∗)

205 Pr imi t ive =[”−”]( I n t e g r a l | Float ing ) |

207 St r ing |Char |

209 Bool ;I n t e g r a l = (DecimalNumeral | HexNumeral | OctalNumeral ) ;

211 DecimalNumeral = ”0” | NonzeroDigit {Dig i t } ;HexNumeral = ”0x” Hexit {Hexit } ;

213 OctalNumeral = ”0” Oct i t {Oct i t } ;Oct i t = ”0” | NonzeroOctit ;

215 Dig i t = ”0” | NonzeroDigit ;NonzeroDigit = NonzeroOctit | ”8” | ”9” ;

217 NonzeroOctit = ”1” | ”2” | ”3” | ”4” | ”5” | ”6” | ”7” ;Hexit = Dig i t | ”a ” . . ” f ” | ”A” . . ”F” ;

219 F loat ing = Dig i t {Dig i t } ” .” F loatTa i l ;F loa tTa i l =

221 Dig i t {Dig i t } [ Exponent ] |Exponent ;

223 Exponent = (”E” | ”e ”) [”+” | ”−”] D ig i t {Dig i t } ;S t r ing = ””” {Let t e r | ” ’”} ””” ;

225 Char = ” ’” ( Let t e r | ”””) ” ’” ;Bool = ”True” | ”Fal se ” ;

227

229 (∗ Misce l l aneous Syntax ∗)(∗

231 I d e n t i f i e r f o r a value . Must s t a r t with an ASCIILower ,and not r e s u l t in a r e s e rved i d e n t i f e r .

233 ∗)Id = (ASCIILower{ IdChar }) − ReservedId ;

235 IdChar = ASCIILetter | Dig i t | ” ” ;

237 (∗ The s e t o f Sard ’ s b inary ope ra to r s . ∗)BinaryOp =

239 Equa l sSu f f i xab l e | ( Equa l sSu f f i x ab l e ”=”) | ”&&” | ” | | ” |”<” | ”>” | ”<=” | ”>=” | ”==” | ”!=”;

241(∗

Page 41: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

3.2. Syntax Specification 33

243 Those ope ra to r s f o r whom there e x i s t s a form o f them su f f i x e dwith ”=”. That ’ s a shorthand f o r ” Id = Id BinaryOp Expr ” .

245 ∗)Equa l sSu f f i xab l e =

247 ”+” | ”−” | ”∗” | ”/” | ”ˆ” | ” |” |”&” | ”>>” | ”>>>” | ”<<” | ”%” ;

249UnaryOp = ”−” | ”˜” | ” !” ;

251 ASCIILetter = ASCIILower | ASCIIUpper ;ASCIILower = ? The ASCII Le t t e r s a−z ? ;

253 ASCIIUpper = ? The ASCII Le t t e r s A−Z ? ;Le t t e r =

255 Pr intab leUnicode |”\”( CodePoint | Escape ) ;

257 Pr intableUnicode = ? Any p r i n t ab l e Unicode charac t e r ? ;CodePoint = ”u” Hexit Hexit Hexit Hexit ;

259 Escape = ”b” | ” t ” | ”n” | ” f ” | ” r ” | ””” | ” ’” | ”\” ;

261 (∗ Sard ’ s r e s e rved i d e n t i f i e r s a . k . a keywords . ∗)ReservedId =

263 ” as ” | ” case ” | ” catch ” | ” c l a s s ” | ” de f ” | ”do” |” e l s e ” | ” f i n a l l y ” | ” i f ” | ” import ” | ”match” |

265 ” ob j e c t ” | ” ove r r i d e ” | ” p r i va t e ” | ” protec ted ” |” re turn ” | ” s ea l ed ” | ” super ” | ” t h i s ” | ”throw” |

267 ” t r a i t ” | ” try ” | ” type” | ” va l ” | ”var ” |”whi l e ” | ”with” ;

269 Comment = ”//”{Unicode }”\n” | ”/∗”{Unicode }”∗/” ;

Page 42: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

34 Chapter 3. Syntax

Page 43: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

Chapter 4

Type System

The type system of Sard may largely be assumed to work as per the Scalaspecification.[7] There are two exceptions to this principle: A number of Scala’sfeatures have been removed, and the set of primitive types have changed quitea bit. We already discussed point the first change in chapter one. Now it’stime to detail Sard’s primitive type hierarchy.

There are a number of reasons why I created a new set of primitive typesfor Sard. The most important one being that Scala has a set of primitive typesborrowed from Java, and thus mostly skipped this problem.

Another reason is that Scala, C# and Java all designed their primitivetypes in a somewhat problematic fashion. All of the above define too manyoperations in their root types, so that they are ”defined” on everything, withoutnecessarily doing anything useful. For example, toString in Java and Scala bydefault prints the bytes of an Object encoded as ASCII. Similarly, equals isdefined on everything as well, but only checks reference equality. Which hasthe twin negative effect of making equals type-unsafe, and making referenceequality impossible to check if one has overridden equals.

Yet another reason for doing so is that Scala, for the purposes of abstractingover it’s primitive types, makes heavy use of implicit conversions from primitiveJava types to rich Scala types. Since implicits have been removed, we need anew set of abstractions.

The solution to these problems is primitive traits; Some traits, as discussedpreviously, which are hardcoded into the compiler, and which are implementedon the primitive types. Thus we move methods like equals which are onlyusefully defined on some things into primitive traits. And a much more type-safe language ensues.

In this chapter, I will describe all special types, primitive types and primitivetraits.

35

Page 44: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

36 Chapter 4. Type System

4.1 Special Types

Some types have a special status in the type system. Either because they,like Any and Nothing, are a ”top” or ”bottom” type, or because they affectbehavior under memory management.

All user-defined types are assumed to extend one of Any, Reference andValue. If none of the above is specified, classes and objects assumes that it is aReference and traits assume that they are an Any. The last choice is possiblebecause traits are abstract, and thus do not have a behavior under garbagecollection. However, if one wishes a certain trait’s subclasses to all be Value orReference subclasses, one may mix in either Value or Reference into that trait.

4.1.1 trait Any

Any is Sard’s top type. I.e. all other types are a subtype of Any. Unlike Scalaand most other static OO languages, anything defined here must be definableon precisely everything. Hence, this trait only contains a method that checkstype membership.

1 // Returns t rue i f the a f f e c t e d o b j e c t i s an ins tance o f T.def isA [T ] : Bool

4.1.2 trait Reference

A Reference is a reference type, which is allocated on the heap, and thengarbage collected. Unlike most other types, Reference has an effect on a object’smemory behavior. It also has the property that is must be distinct from Value.Any given object cannot mix in both, for that will result in a type error.

// Checks r e f e r ence e q u a l i t y with another re f e r ence .2 sealed def eq ( that : Reference ) : Bool

sealed def neq ( that : Reference ) : Bool = ! eq ( that )4

/∗6 This method i s c a l l e d be f o r e the o b j e c t i s

garbage c o l l e c t e d . I t ’ s intended to be used to d i spense8 resources the c l a s s may have a l l o c a t e d other than memory .

∗/10 def f i n a l i z e : Unit

4.1.3 trait Value

Value types are allocated on the stack, and persist until the current scope isexited. As previously mentioned, Value and Reference need to be distinct, forobvious reasons. Value defines no other behavior.

Page 45: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

4.2. Primitive Traits 37

4.1.4 sealed trait Nothing

Nothing is also unique in that it is a bottom type. That is, it is considered asubtype of everything else in the type system. Nothing is used as a sentinelvalue to indicate lack of a value. For example: Suppose that one has a typeList[T], which may either be a Cons pair or Nil. What is the type of T in theempty list Nil? T is supposed to be the element type, but since Nil has noelements, it is difficult to give it a reasonable value. This is where Nothingcomes in. One can then say that the empty List extends List[Nothing]. Noth-ing, being a type sentinel value only, has no behavior and no value associatedwith it. It may not be extended.

4.2 Primitive Traits

These are the aforementioned primitive traits. Note that some of these defineoperators. These operators are as previously mentioned in the section on op-erator overloading not user-extensible, but their behavior may be changed byimplementing some attending methods.

4.2.1 trait Showable

Showable is a trait for things which may be turned into a String. It is theequivalent of toString in Java.

def show : S t r ing

4.2.2 trait Binary

Binary, similarly to Showable, is trait for things which may be turned into abytestring.

1 def bytes : Array [ Byte ]

4.2.3 trait Hashable

Hashable types can be turned into a unsigned 32-bit hash code.

1 def hashCode : UInt

Page 46: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

38 Chapter 4. Type System

4.2.4 trait Equality[A]

Equality[A] is a trait that controls value equality. It is the equivalent of equals()in Java. It defines a method that checks value equality, as well as the operators== and !=, with the expected behaviors.

It also requires Hashable, which should be implemented in such a way thatthis == that logically implies this.hashCode == that.hashCode.

Implemented Traits: Hashable

1 def equa l s ( that :A) : Booldef equa l s ( that :A) : Bool

3 sealed def ==(that :A) : Bool = this . equa l s ( that )sealed def !=( that :A) : Bool = ! ( this == that )

4.2.5 trait Ordered[A]

Ordered[A] is a total ordering over objects of type A. See also the primitivetype Ordering. Implemented Traits: Equality[A]

def equa l s ( that :A) : Bool = this . compare ( that ) == Equal2 def compare ( that :A) : Ordering

4 sealed def >( that :A) : Bool = this . compare ( that ) == Greatersealed def <( that :A) : Bool = this . compare ( that ) == Less

6 sealed def <=(that :A) : Bool = ! ( this > that )sealed def >=(that :A) : Bool = ! ( this < that )

8sealed def min( that :A) :A = i f ( this <= that ) this else that

10 sealed def max( that :A) :A = i f ( this >= that ) this else that

4.2.6 trait Enumerable[A]

An Enumerable[A] is an enumerable set. Implemented Traits: Ordered[A]

// Should be implemented so x . prev < x and v i c e versa .2 def prev :A

def next :A

4.2.7 trait Exception

Exception is a supertrait for any type that can be thrown like an error. Imple-mented Traits: Reference, Showable

1 def message : S t r ingdef s t a ckSt rac e : S t r ing

Page 47: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

4.2. Primitive Traits 39

4.2.8 trait Monoid[A]

A Monoid is a type that can be added to another Monoid. It is based on themathematical category of the same name.

def add ( that :A) :A2 sealed def +(that :A) :A = this . add ( that )

4.2.9 trait Numeric[A]

Numeric[A] is a Monoid which is also a number.Implemented Traits: Monoid[A]

def abs :A2 def s i gn :A

sealed def −:Numeric = this . negate4 def negate : Numeric = 0 − this

sealed def −( that :A) :A= this . subt rac t ( that )6 def subt rac t ( that :A) :A

sealed def ∗( that :A) :A = this . mul t ip ly ( that )8 def mult ip ly ( that :A) :A

4.2.10 trait Integral[A]

An Integral is a Numeric which is a whole number (integer). It implementsinteger modulo and integer division.

Implemented Traits: Numeric[A]

sealed def %(that :A) :A = this .mod( that )2 def mod( that :A) :A

sealed def // ( t ha t :A) :A = t h i s . d i v ( t ha t )4 def div ( that :A) :A

4.2.11 trait Fractional[A]

A Fractional is anything that is (non-integrally) divisible. Implemented Traits:Numeric[A]

sealed def /( that :A) :A = this . d i v i d e ( that )2 def d iv id e ( that :A) :A

Page 48: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

40 Chapter 4. Type System

4.2.12 trait NumberConvertible

A NumberConvertible must be convertible to all the primitive number types.

def toSByte : SByte2 def toByte : Byte

def toShort : Short4 def toUShort : UShort

def t o In t : Int6 def toUInt : UInt

def toLong : Long8 def toULong : ULong

def toF loat : Float10 def toDouble : Double

def toLongDouble : LongDouble

4.2.13 trait Bitwise[A]

A Bitwise is a whole number represented in two-complement form. Does notrequire Integral as it is unnecessary for this class’s functionality.

1 sealed def ˜ :A = this . negateBinarydef negateBinary :A

3 sealed def &(that :A) :A = this . and ( that )def and ( that :A) :A

5 sealed def | ( that :A) :A = this . or ( that )def or ( that :A) :A

7 sealed def ˆ( that :A) :A = this . xor ( that )def xor ( that :A) :A

9 sealed def <<(shamt : Byte ) :A = this . s l l ( shamt )def s l l ( shamt : Byte ) :A

11 sealed def >>(shamt : Byte ) :A = this . s r a ( that )def s ra ( shamt : Byte ) :A

13 sealed def >>>(shamt : Byte ) :A = this . s r l ( that )def s r l ( shamt : Byte ) :A

4.2.14 trait Floating[A]

A Floating is a floating-point number.

def trunc :A2 def round :A

def c e i l :A = this . t runc + 1 .04 def f l o o r :A = this . t runc − 1 .0

def i s I n f i n i t y : Bool6 def isNaN : Bool

def i sN e g a t i v e I n f i n i t y : Bool8 def i s P o s i t i v e I n f i n i t y : Bool

Page 49: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

4.3. Primitive Types 41

4.3 Primitive Types

These are concrete primitive types. To save time I will not specify how theprimitive types implement traits. In any case most of those operations to beimplemented are not illustratable in Sard source code. It is also generallyobvious how they should be implemented.

4.3.1 object System

System is an object containing some utility methods which do not have a betterplace to be.

//The epoch (UNIX) time in mi l l i s e c ond s .2 def epochTime :ULong

//Terminates the VM with t ha t e x i t code .4 def e x i t ( s t a tu s : Int = 0) : Unit

//Runs the garbage c o l l e c t o r .6 def gc : Unit

//Fetches a re f e r ence to the thread invok ing t h i s method .8 def currentThread : Thread

4.3.2 class Type

A type which is a value representation of some other type. Created in pat-tern matching when binding type members to variables. Implemented Traits:Equality[Type],Showable

4.3.3 sealed trait Ordering

Ordering is an enumeration which tells of the ordering between two types thatimplement Ordered[A]. Implemented Traits: Value, Equality[Ordering].

object Less with Ordering2 object Equal with Ordering

object Greater with Ordering

4.3.4 class Lock

Lock is a common binary semaphore. It may be atomically acquired or released.Any thread waiting to acquire the lock will block until the Lock is acquired.When it is acquired the thread will be woken up. When multiple threads arewaiting on a lock, they will be given the lock in FIFO order.

Page 50: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

42 Chapter 4. Type System

1 // Acquires the l o c k .def l o ck : Unit

3 // Like above but only wai t s m i l l i s m i l l i s e c ond s .// Returns t rue i f l o c k was acquired .

5 def lockWait ( m i l l i s : UInt ) : Bool// Releases the l o c k .

7 def unlock : Unit

4.3.5 class Thread

A Thread is a, well, thread.

1 // Create a new thread execu t ing t h i s t a s k .def this ( task :=> Unit )

3 // Blocks u n t i l t h i s thread e x i t s .def j o i n : Unit

5 // Wait m i l l i s m i l l i s e c ond s f o r t h i s thread to terminate .// Returns True i f the thread terminated in time .

7 def wait ( m i l l i s : UInt ) : Bool// Forces t h i s thread to terminate .

9 def i n t e r r up t : Unit

4.3.6 class Array[Elem]

An Array is a common array. It is polymorphic and non-resizable.

1 // Create new empty array with room for l eng t h c e l l s .def this ( l ength : UInt )

3 // Create new array from many elements .def this ( xs : Elem∗)

5 // Extrac t one element .def apply ( i : UInt ) : Elem

7 // Set one element .def update ( i : UInt , x : Elem) : Unit

9 // Checks i f i i s s e t .def i sDe f inedAt ( i : UInt ) : Bool

4.3.7 sealed trait Bool

The common Boolean.Implemented Traits:

1. Value

2. Eq[Bool]

3. Binary

4. Showable

Page 51: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

4.3. Primitive Types 43

object True with Bool2 object False with Bool

sealed def ! : Bool4 sealed def &&(that : Bool ) : Bool

sealed def | | ( that : Bool ) : Bool

4.3.8 class Char

A single Unicode character.Implemented Traits:

1. Value

2. Ordered[Char]

3. Enumerable[Char]

4. Showable

5. Binary

1 // Create new char from code po in t or another char .def this ( codePoint : UInt )

3 def this ( o ld : Char ) = this ( o ld . codePoint )

5 // Gets t h i s charac ter ’ s Unicode code po in t .def codePoint : UInt

7// Sets t h i s Char to upper or lowercase .

9 def toLower : Chardef toUpper : Char

11// Fetches the Unicode category o f t h i s charac ter .

13 def category : UnicodeCategory

15 // Sp e c i f i c in s tance s o f t h i s . ca tegory == xdef i sLower : Bool

17 def i sUpper : Booldef i sCon t r o l : Bool

19 def i sD i g i t : Booldef i s L e t t e r : Bool

21 def i sL e t t e rOrD ig i t : Booldef i sWhiteSpace : Bool

4.3.9 sealed trait UnicodeCategory

An enumeration which encodes the Unicode category of a character.Implemented Traits:

1. Value

Page 52: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

44 Chapter 4. Type System

2. Equality[UnicodeCategory]

3. Showable

object ClosePunctuat ion with UnicodeCategory2 object ConnectorPunctuation with UnicodeCategory

object Control with UnicodeCategory4 object CurrencySymbol with UnicodeCategory

object DashPunctuation with UnicodeCategory6 object DecimalDigitNumber with UnicodeCategory

object EnclosingMark with UnicodeCategory8 object FinalQuotePunctuation with UnicodeCategory

object Format with UnicodeCategory10 object In i t i a lQuotePunctuat ion with UnicodeCategory

object LetterNumber with UnicodeCategory12 object LineSeparator with UnicodeCategory

object LowercaseLetter with UnicodeCategory14 object MathSymbol with UnicodeCategory

object Mod i f i e rLe t t e r with UnicodeCategory16 object Modif ierSymbol with UnicodeCategory

object NonSpacingMark with UnicodeCategory18 object OpenPunctuation with UnicodeCategory

object OtherLetter with UnicodeCategory20 object OtherNotAssigned with UnicodeCategory

object OtherNumber with UnicodeCategory22 object OtherPunctuation with UnicodeCategory

object OtherSymbol with UnicodeCategory24 object ParagraphSeparator with UnicodeCategory

object PrivateUse with UnicodeCategory26 object SpaceSeparator with UnicodeCategory

object SpacingCombiningMark with UnicodeCategory28 object Surrogate with UnicodeCategory

object T i t l e c a s eL e t t e r with UnicodeCategory30 object UppercaseLetter with UnicodeCategory

4.3.10 class SByte

A signed 8-bit integer.Implemented Traits:

1. Value

2. Showable

3. Binary

4. Enumerable[SByte]

5. Integral[SByte]

6. NumberConvertible

7. Bitwise[SByte]

8. Ordered[SByte]

Page 53: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

4.3. Primitive Types 45

4.3.11 class Byte

An unsigned 8-bit integer.Implemented Traits:

1. Value

2. Showable

3. Binary

4. Enumerable[Byte]

5. Integral[Byte]

6. NumberConvertible

7. Bitwise[Byte]

8. Ordered[Byte]

4.3.12 class Short

A signed 16-bit integer.Implemented Traits:

1. Value

2. Showable

3. Binary

4. Enumerable[Short]

5. Integral[Short]

6. NumberConvertible

7. Bitwise[Short]

8. Ordered[Short]

4.3.13 class UShort

An unsigned 16-bit integer.Implemented Traits:

1. Value

2. Showable

3. Binary

Page 54: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

46 Chapter 4. Type System

4. Enumerable[UShort]

5. Integral[UShort]

6. NumberConvertible

7. Bitwise[UShort]

8. Ordered[UShort]

4.3.14 class Int

A signed 32-bit integer.Implemented Traits:

1. Value

2. Showable

3. Binary

4. Enumerable[Int]

5. Integral[Int]

6. NumberConvertible

7. Bitwise[Int]

8. Ordered[Int]

4.3.15 class UInt

An unsigned 32-bit integer.Implemented Traits:

1. Value

2. Showable

3. Binary

4. Enumerable[UInt]

5. Integral[UInt]

6. NumberConvertible

7. Bitwise[UInt]

8. Ordered[UInt]

Page 55: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

4.3. Primitive Types 47

4.3.16 class Long

A signed 64-bit integer.Implemented Traits:

1. Value

2. Showable

3. Binary

4. Enumerable[Long]

5. Integral[Long]

6. NumberConvertible

7. Bitwise[Long]

8. Ordered[Long]

4.3.17 class ULong

An unsigned 64-bit integer.Implemented Traits:

1. Value

2. Showable

3. Binary

4. Enumerable[ULong]

5. Integral[ULong]

6. NumberConvertible

7. Bitwise[ULong]

8. Ordered[ULong]

4.3.18 class Float

A 32-bit floating-point.Implemented Traits:

1. Value

2. Showable

3. Binary

Page 56: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

48 Chapter 4. Type System

4. Ordered[Float]

5. Fractional[Float]

6. NumberConvertible

7. Floating[Float]

4.3.19 class Double

A 64-bit floating-point.Implemented Traits:

1. Value

2. Showable

3. Binary

4. Ordered[Double]

5. Fractional[Double]

6. NumberConvertible

7. Floating[Double]

4.3.20 class LongDouble

A 128-bit floating-point.Implemented Traits:

1. Value

2. Showable

3. Binary

4. Ordered[LongDouble]

5. Fractional[LongDouble]

6. NumberConvertible

7. Floating[LongDouble]

4.3.21 class IndexOutOfBounds

A subclass of exception that says that an array index is out of bounds.

def this ( val idx : UInt )

Page 57: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

4.3. Primitive Types 49

4.3.22 class IndexUndefined

A subclass of exception that says that an array index is unset.

1 def this ( val idx : UInt )

4.3.23 class Overflow/class Underflow

Exceptions that tell of numerical over/underflow.

4.3.24 class DivideByZero

An exception that informs about division by zero.

4.3.25 class IllegalArgument

An exception thrown when a parameter on a method does not satisfy somenecessary condition.

4.3.26 class OutOfMemory

An exception thrown when the VM runs out of memory.

4.3.27 class StackOverflow

An exception thrown when the VM runs out of stack space.

4.3.28 class RefutedPattern[A]

Exception thrown when a value fails to match any pattern in a pattern match-ing. Contains reference to the offending value.

1 def this ( re futedValue :A)val re futedValue :A

Page 58: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

50 Chapter 4. Type System

Page 59: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

Chapter 5

Conclusions

This project has come a far way since it was a Scheme variant; It is now anentirely new programming language, one that I would not mind writing somecode in. I hope that once this language has an implementation, others willagree.

But more importantly, it is the end of a great personal journey for myself.In the process of creating this specification, I’ve learned a great deal about com-puter science in general and compilers in particular. I’ve grown as a computerscientist, and discovered that I rather enjoy doing this sort of thing.

While this is an end, is it not said that most of them are also beginnings? Forme, that would be the beginning of advanced studies, and on writing a compilerfor this language. A prospect I look forward to with great anticipation!

5.1 Acknowledgments

I wish to acknowledge several of the graduate students present at my seminarof Sard’s feature set. Johan Granberg pointed out that binding methods inpattern matching might be useful. Another person present whom I have notbeen able to contact suggested removing single inheritance.

5.2 Limitations

Originally, I intended to make Sard significantly simpler than Scala. I did notmake much progress with this; While Sard is maybe slightly simpler than Scalaon account of being more orthogonal, the feature sets of both languages areapproximately equally large.

51

Page 60: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

52 Chapter 5. Conclusions

5.3 Future Work

In the future, more or less everything remains to be done. The most obviousthing to do is the compiler. I must also specify some type of calling compati-bility to other language and how primitive types implement their traits. Afterthat, I must implement a REPL, documentation generation and some libraries.One can only hope I can solicit some aid in doing this; The aforementionedtasks could very easily span several man-years.

Page 61: Sard: An Object-Functional Programming Language · Sard, like Scala, is a high-level object-functional language. Unlike Scala, it is not very closely tied to the JVM or Java, eliminat-ing

References

[1] Jeff Atwood. Xml: The angle-bracket tax, 2008.

[2] Eric Browne. The myth of self-describing xml, 2003.

[3] Tony Hoare. Null references: The billion dollar mistake, 2009.

[4] Martin Odersky. The scala experiment, 2006.

[5] Martin Odersky. Poor man’s type classes, 2007.

[6] Martin Odersky. The scala experience, 2007.

[7] Martin Odersky. The Scala Language Specification - Version 2.8. EPFL,2009.

[8] Stephen Blott Philip Wadler. How to make ad-hoc polymorphism lessad-hoc, 1989.

[9] Hugo Svallfors. Ystack: A functional, stack based programming language,2010.

[10] Hugo Svallfors. Sard: An object-functional programming language - thesisproposal, 2011.

[11] Dean Wampler. Programming Scala. O’Reilly Media, 2008.

53