Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language...

61
Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 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: An Object-Functional Programming Language...

Page 1: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

Sard: An Object-FunctionalProgramming Language

Hugo Svallfors

June 20, 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: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.
Page 3: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

Abstract

This bachelors thesis concerns the specification of a new programming language.This language, called Sard, is similar to, but incompatible with, the existinglanguage Scala. Sard, like Scala, is a high-level object-functional language.Unlike Scala, it is not very closely tied to the JVM or Java, eliminating someconstraints on the languages design. Since this necessitates breaking backwardscompatibility with Scala, the opportunity to disregard it is used to fix someof the authors irritations with the language. This thesis mostly focuses ondeciding on the exact changes to Scala, and on the overall design, rather thanon implementing a compiler for the language. A reason for this is that there isinsufficient time to properly implement and debug a compiler. Another is thedesirability of pushing changes to the language as early into the design processas possible. Preferably, almost all changes to the language should occur beforeany compiler code has been written.

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 Scalas design.

Page 4: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

ii

Page 5: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

Contents

1 Introduction 1

1.1 Why make a new language? . . . . . . . . . . . . . . . . . . . . 2

1.2 Problem Description . . . . . . . . . . . . . . . . . . . . . . . . 3

1.3 Overall Vision . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

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 Rectified Generics . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.8 Type Members . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.9 ML-Like Pattern Matching . . . . . . . . . . . . . . . . . . . . 10

2.10 Null Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

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

2.12 All statements return a value . . . . . . . . . . . . . . . . . . . 13

2.13 Default Values for Parameters . . . . . . . . . . . . . . . . . . . 14

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

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

2.16 Infix Syntax for Methods . . . . . . . . . . . . . . . . . . . . . 15

2.17 Structural Subtyping . . . . . . . . . . . . . . . . . . . . . . . . 16

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

2.19 Module and Import System . . . . . . . . . . . . . . . . . . . . 17

iii

Page 6: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

iv CONTENTS

2.20 Variable Arguments . . . . . . . . . . . . . . . . . . . . . . . . 18

2.21 Local Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

2.22 Syntactic sugar for Array/Table Mutation . . . . . . . . . . . . 18

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

2.24 C-Style Loops and their jump instructions . . . . . . . . . . . . 19

2.25 Checked Exceptions . . . . . . . . . . . . . . . . . . . . . . . . 19

2.26 Switch Instructions . . . . . . . . . . . . . . . . . . . . . . . . . 20

2.27 XML-Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

2.28 Tail-Call Optimization . . . . . . . . . . . . . . . . . . . . . . . 21

2.29 Annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

2.30 Uniform Access . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

2.31 Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

2.32 Variance Annotations . . . . . . . . . . . . . . . . . . . . . . . 22

2.33 Multi-Line Strings . . . . . . . . . . . . . . . . . . . . . . . . . 23

2.34 Named Arguments . . . . . . . . . . . . . . . . . . . . . . . . . 23

2.35 Optional Dynamic Typing . . . . . . . . . . . . . . . . . . . . . 23

2.36 Existential Types . . . . . . . . . . . . . . . . . . . . . . . . . . 24

2.37 Self-Type Annotations . . . . . . . . . . . . . . . . . . . . . . . 24

2.38 Higher-Kinded Generics . . . . . . . . . . . . . . . . . . . . . . 24

2.39 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 sealed trait Nothing . . . . . . . . . . . . . . . . . . . . 36

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

4.2.1 trait Cloneable[A] . . . . . . . . . . . . . . . . . . . . . 37

4.2.2 trait Showable . . . . . . . . . . . . . . . . . . . . . . . 37

4.2.3 trait Binary . . . . . . . . . . . . . . . . . . . . . . . . . 37

4.2.4 trait Equality[A] . . . . . . . . . . . . . . . . . . . . . . 37

4.2.5 trait Hashable . . . . . . . . . . . . . . . . . . . . . . . 37

4.2.6 trait Ordered[A] . . . . . . . . . . . . . . . . . . . . . . 38

Page 7: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

CONTENTS v

4.2.7 trait Enumerable[A] . . . . . . . . . . . . . . . . . . . . 38

4.2.8 trait Exception . . . . . . . . . . . . . . . . . . . . . . . 38

4.2.9 trait Numeric[A] . . . . . . . . . . . . . . . . . . . . . . 38

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

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

4.2.12 trait NumberConvertible . . . . . . . . . . . . . . . . . . 39

4.2.13 trait Bitwise[A] . . . . . . . . . . . . . . . . . . . . . . . 39

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

4.2.15 trait FunctionN[-A,-B,-C..,-N,+R] . . . . . . . . . . . . 40

4.2.16 trait Lazy[+A] . . . . . . . . . . . . . . . . . . . . . . . 40

4.2.17 trait PartialFunction[-A,+B] . . . . . . . . . . . . . . . 40

4.2.18 trait Updateable[+K,+V] . . . . . . . . . . . . . . . . . 41

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

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

4.3.2 sealed trait Ordering . . . . . . . . . . . . . . . . . . . . 41

4.3.3 class Lock . . . . . . . . . . . . . . . . . . . . . . . . . . 41

4.3.4 class Thread . . . . . . . . . . . . . . . . . . . . . . . . 42

4.3.5 class Array[Elem] . . . . . . . . . . . . . . . . . . . . . . 42

4.3.6 class TupleN[+A,+B,..+N] . . . . . . . . . . . . . . . . 42

4.3.7 sealed trait Bool . . . . . . . . . . . . . . . . . . . . . . 43

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

4.3.9 class String . . . . . . . . . . . . . . . . . . . . . . . . . 44

4.3.10 sealed trait UnicodeCategory . . . . . . . . . . . . . . . 44

4.3.11 class SByte . . . . . . . . . . . . . . . . . . . . . . . . . 45

4.3.12 class Byte . . . . . . . . . . . . . . . . . . . . . . . . . . 45

4.3.13 class Short . . . . . . . . . . . . . . . . . . . . . . . . . 46

4.3.14 class UShort . . . . . . . . . . . . . . . . . . . . . . . . 46

4.3.15 class Int . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4.3.16 class UInt . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4.3.17 class Long . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4.3.18 class ULong . . . . . . . . . . . . . . . . . . . . . . . . . 48

4.3.19 class Float . . . . . . . . . . . . . . . . . . . . . . . . . . 48

4.3.20 class Double . . . . . . . . . . . . . . . . . . . . . . . . . 48

4.3.21 class LongDouble . . . . . . . . . . . . . . . . . . . . . . 49

4.3.22 class IndexOutOfBounds . . . . . . . . . . . . . . . . . . 49

4.3.23 class IndexUndefined . . . . . . . . . . . . . . . . . . . . 49

4.3.24 class Overflow/class Underflow . . . . . . . . . . . . . . 49

Page 8: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

vi CONTENTS

4.3.25 class DivideByZero . . . . . . . . . . . . . . . . . . . . . 49

4.3.26 class IllegalArgument . . . . . . . . . . . . . . . . . . . 49

4.3.27 class OutOfMemory . . . . . . . . . . . . . . . . . . . . 49

4.3.28 class StackOverflow . . . . . . . . . . . . . . . . . . . . 49

4.3.29 class RefutedPattern[A] . . . . . . . . . . . . . . . . . . 50

5 Conclusions 51

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

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

5.3 Alternate Solutions . . . . . . . . . . . . . . . . . . . . . . . . . 51

5.3.1 Keeping Higher-Ranked Generics . . . . . . . . . . . . . 51

5.3.2 Keeping Type Members . . . . . . . . . . . . . . . . . . 52

5.4 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

References 53

Page 9: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

Chapter 1

Introduction

This bachelors thesis concerns the specification of a new programming language.This language, called Sard, is similar to, but incompatible with, the existinglanguage Scala. Scala is a so-called object-functional language on the Javavirtual machine. The language is an attempt of combining object orientationwith functional programming.

According to Scalas creator, Martin Odersky, functional programming makesit easier to build things from simple parts, whereas object orientation makesit simple to extend complex systems [Odersky(2007a)]. To paraphrase this ob-servation slightly, functional programming works best when programming inthe small, and object orientation works best when programming in the large.When phrased like so, the potential synergy between the two becomes obvious:Why not make programming in the large and small easy by combining them?

Functional programming has been characterized as an idiom of program-ming which makes heavy use of first-class functions, and seeks to minimizeside-effects. Object-orientation on the other hand is an idiom which revolvesaround the encapsulation of behavior and state in objects. The idiom of object-functional programming can thus be summarized as encapsulating state andbehavior in immutable objects, some of which are closures.

For a more in-depth look at Scala, the O’Reilly book ”Programming Scala”[Wampler(2008)] is recommended. There will also be some examples duringthe discussion of Scalas feature set. The reader may also wish to peruse theScala specification [Odersky(2009)] for some grasp of Scalas syntax and typesystem, although this is not strictly necessary.

1

Page 10: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

2 Chapter 1. Introduction

1.1 Why make a new language?

Scala has from the outset been very closely tied to Java and the JVM. Alreadyat its inception Scala was envisioned as a JVM language with full Java callingcompatibility. However, Odersky thinks that doing so was a ”double-edgedsword” [Odersky(2006)].

In doing so, they gained the strength of Javas 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 true virtualclasses, the adoption of null references and limited tail recursion among these[Odersky(2006)].

Although the above are certainly problematic, arguably there are moreproblems that crop up because of Java: The presence of dynamic types andthe non-presence of unsigned integers.

As the reader may know, Java is about to have its 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 its 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 theprogrammers 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 has also been lacking any form of unsigned integer. This means thatit is 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.

In summary, while the foundational idiom of Scala is sound, maybe evenbrilliant, it is limited by its implementation on the JVM. Close dependence onJava is holding Scalas design back in a number of key areas. And perhaps mostworryingly, Java is currently changing in ways incompatible with Scala. TheScala team has little to no recourse in reacting to these changes; As long asScala wishes to maintain calling compatibility with Java, all of these problems

Page 11: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

1.2. Problem Description 3

are intractable.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.”

This is the goal of this thesis.

1.2 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 its very well maintainedvirtual machines as well as having some features that Java lacks. An effort willbe made to reduce dependence on .NET, so that the option of having otherimplementations on per example LLVM remains open. This will also ensurethat .NET-isms like null pointers and single inheritance do not make it intothe language.

The goal of this bachelors thesis is to identify the exact subset to implement,and to create a specification for it. This specification should at a very minimumcontain 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.

Unfortunately, there is not sufficient time to implement and debug a com-piler. Therefore, this work will not concern itself with the implementation ofthis specification. It is also desirable to receive feedback on what to implementbefore much code has been written. This will make it easier to change thespecification, should the need arise.

Page 12: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

4 Chapter 1. Introduction

1.3 Overall Vision

The overall vision for Sard is that of a safe and expressive language. Onewhere code is terse, and has relatively few ways to fail. One might ask whyexpressiveness and type-safety are considered the most important qualities, asopposed to a host of others like speed, readability e.t.c. This is because theseare the qualities that have the greatest effect on development time.

Expressiveness obviously cuts down on development time, by allowing moreto be done with the same amount of typing. This will make implementing aprogram more simple. A more controversial opinion is that static type-safetycan also cut down on development time. In the authors anecdotal opinion,debugging any given program takes much longer time than writing it. So whilecutting down on time to write an application is certainly positive, cuttingdown the time to debug it will have greater overall effect on time to completea project.

In languages without static type-safety and many side effects, it is notpossible to statically guarantee much about any program being written. As aresult, testing must to a greater extent be done manually. This has in certainprogramming communities gone so far that they advocate not writing anythinguntil there is a unit test which covers said code. They are, in the authorsopinion, expending great time and effort doing manually what can and shouldbe done automatically. If even 10% of the time these people spend writing testscould instead go to other tasks, they would greatly benefit.

Thus, Sard is designed for rapid application development, but takes the ap-proach that this is best done in (expressive) statically typed languages. Havingtype safety enables one to guarantee some properties automatically withoutwriting unit tests for them, thus ultimately saving the time of everyone in-volved.

Many companies and research projects are greatly constrained in the time-frame they have in completing their goals. And even those projects that do nothave a strict time-frame (like open-source ones), will find that the additionaltime can be reinvested in additional features or more thorough testing.

Sard should thus be widely applicable, but especially useful in situationswhere programmer time is more expensive than computer time.

Page 13: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

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 Scalasbasic syntax [Odersky(2009)] will be needed to understand this chapter. Forfurther reading on how Scala works, refer to the excellent O’Reilly book onScala [Wampler(2008)], which is freely available online.

2.1 Type Inference

In Scala, any type signatures in an expression context (i.e. on fields and in-side methods) are optional. If not specified, the compiler will infer types forexpressions. 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 andJavas single inheritance with interfaces. A trait is basically an 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.

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

5

Page 14: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

6 Chapter 2. Feature Set

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, it is considered a given that traits have to be in Sard.However, there are two ways in which it has been changed relative to Scala;Inheritance 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, making them explicit wouldaid in debugging them. On occurrence of the error, the programmer can thentake steps 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.

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

Page 15: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

2.3. Compound Types 7

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. Scalas 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.

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

Page 16: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

8 Chapter 2. Feature Set

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 its parameters, thus defining a new function.

1 def isMod (x : Int , d iv : 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 is

Page 17: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

2.6. Tuples 9

somewhat 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 convenient when one wishes to return multiple values froma function.

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

class Tuple2 [+A,+B] ( val 1 :A, val 2 :B)2 class Tuple3 [+A,+B,+C] ( val 1 :A, val 2 :B, val 3 :C)

// And so on . .4

// These are e qu i v a l en t6 val aPair : Tuple2 [ Int , Int ] = Tuple2 (5 , 2 )

val eqPair : ( Int , Int ) = (5 , 2 )

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

2.7 Rectified 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.

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.

1 trait AbsCell {type T

3 val c e l l :T}

5class I n tCe l l (var c e l l : Int ) extends AbsCell {

7 type T = Int}

9val t e s t : AbsCell = new I n tCe l l (10)

11 t e s t . c e l l // 10t e s t . c e l l = 12

Page 18: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

10 Chapter 2. Feature Set

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.

// Limit T to sub types o f Numeric wi thout s p e c i f y i n g what T i s .2 trait NumericCell extends AbsCell {

type T <: Numeric4 }

Taken together, this means that type members are much better suited thangenerics to when one has 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 on for howevermany steps one must inherit it.

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

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

trait Type3 extends Type2 [ Int ]6

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

trait Type1 extends Base10 trait Type2 extends Type1

trait Type3 extends Type2 {type T = Int ;}

That is not to say that type parameters have no place however. For typemembers are not accessible in subtyping checks. They do not count for sub-typing purposes, and if one wishes them to do so, they must be parameters.

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 expres 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 rns .

Page 19: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

2.9. ML-Like Pattern Matching 11

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 ) => −519 case Some [ Int ] ( x ) => x

case None => 021 }

The astute reader may have noticed that nothing about pattern matchingcannot 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}

One may notice that, although pattern matching is exactly equivalent todoing a series of ifs 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 Scalas patternmatching, namely that it only works on objects specified in advance. Onemay 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.Due to the fact that Sard is not similarly constrained, we can generalize thatto any slot of any object.

This is Sards 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 }

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

One may per example select methods with patterns.

Page 20: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

12 Chapter 2. Feature Set

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 = tmp . 1val y : Int = tmp . 2

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.

2.10 Null Pointers

Null or uninitialized pointers are one of the leading causes of errors worldwide.They are the billion dollar mistake [Hoare(2009)]. One of the most importantdesign goals of Sard is to make this type of error impossible. In practice, thisturns out to be 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.

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

}

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 constructors first statement to be acall to a constructor that has already been defined. Since the main constructor

Page 21: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

2.11. Syntactic Sugar for Constructors 13

is 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.

The author can take no credit for any of the above. All of these solutionsare already implemented in Scala. However, due to being constrained by Javabackwards compatibility, they need the null pointer to be able to pass nullsin and out of Java methods. Remove the need for Java compatibility, andremoving it becomes 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.

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.

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 t ypes ( 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 =

Page 22: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

14 Chapter 2. Feature Set

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 one may have noticed in the last example, the fact that we printedsomething before returning 1 did not matter. That is because blocks too havea value, and that is 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 is the value of its try- orcatch block. Hence, the try and catch blocks must again have the same type,and the finally block must have type unit.

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 its 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,one which gives default values to the other. When there are three or moredefault values however, this becomes somewhat unwieldy. Therefore, it wouldprobably be best to keep them.

Page 23: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

2.14. Method Overloading 15

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, methods in Sard must be uniquelynamed in their class.

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.

1 class Fooobject Foo

So if one defines a class and an object, in the same file, with the same name,they have the same namespace. This is more or less semantically identical tohaving static members.

It was decided to keep them, as we still need some way of representing staticfunctions that belong to a class. It is 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 // The two l i n e s below are s eman t i ca l l y i d e n t i c a l .

new Example (5 ) mod 36 new Example (5 ) .mod(3)

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.

This means one can do two things which 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.

Page 24: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

16 Chapter 2. Feature Set

It is 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 having two method call syntaxes. Why not justone? They are semantically identical, so why complicate matters?

Due to the above issues, infix syntax from Sard is being removed, alongwith the ability to have anything other than ASCII letters, underscores andnumbers in method names.

This does remove the ability to overload the numerical and comparisonoperators. To reintroduce that functionality, a somewhat C#-like way of over-loading operators is offered.

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

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

}

Anything that implements this trait and defines equals can be used withthe == and != operators. The numerical traits are similarly defined a in traitcalled Numeric[A]. In all cases, the basic pattern is that operators cannot becreated 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. Itmeans declaring this type to be a subtype of the supertype. There is however,another way of doing subtyping, found in O’Caml and Python, where subtypingis structural.

This means that we consider A to be a subtype of B if and only if 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 the A and B example; Just because A has a method foo, does notimply A does what a B expects it to do. Perhaps one defined B.foo to be a

Page 25: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

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

sealed 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 nomina-tive subtyping. A somewhat recurring pattern in Scalas design is that, whenfaced with a decision between two things, they elect to pick both. For somethings, like calling strategies, this approach worked well enough. Arguably,this is not the case here. Having two ways to implement subtyping is a bitgratuitous. Mostly because both subtyping strategies overlap to a rather largedegree. Structural subtyping can use trait-like functionality without definingtraits (by defining a required structure for parameters to methods) and nom-inative subtyping can guarantee invariants by subtyping. But the benefits ofhaving both are, in the authors opinion, too slim to motivate the complexityof doing so. Given that we should aim for one kind of subtyping, nominativewould be preferable, to avoid the issues with only having structural 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-value 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 its result thefirst time its called, and is thereafter not evaluated again.

I am all in favor of keeping this feature, partly because its 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.

Page 26: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

18 Chapter 2. Feature Set

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

Another thing that has been simplified from Scala is that the ability torename classes when importing them is removed. Instead, one can stick tousing path-qualification in the few instances where its 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

2.20 Variable Arguments

In Scala and Sard both its 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 variable arguments where removed, one would have toreplace them with some other form of collection literal. Therefore, it appearsthat they hold an important role in Sard.

2.21 Local Methods

In Scala, it is 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, they will be removed.

2.22 Syntactic sugar for Array/Table Mutation

We have previously seen in ”Subclassable Closures” that an Array can be seenas a function from Int to element. There is also some corresponding syntacticsugar for setting the values of an Array or Table.

Page 27: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

2.23. For-Each Loops and Enumerations 19

1 val t e s t = HashMap [ Str ing , Int ]t e s t . update ( ”one” ,1 )

3 t e s t ( ”one” ) // 1t e s t ( ”two” ) = 2

5 t e s t ( ”two” ) // 2

The syntax test(”two”) = 2 is syntactic sugar for test.update(”two”,2). Thisensures one can use mutable arrays with the same ease as in other languages.However, Sard does not prioritize Arrays over other collection types, so applyis extensible to any collection that is in-place mutable.

2.23 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, unnecessary. The for-eachloop is basically a very simple closure, and the enumeration is a very simplesealed class hierarchy. There is little point to having multiple ways of doingthe same thing.

2.24 C-Style Loops and their jump instructions

Java retains most of the loop instructions from C, along with their jump in-structions break and continue. A strange decision, as Java already has a for-each loop, and removed goto claiming that unconditional jumps are unintuitive.Why then did they not apply the same logic to break and continue?

Fortunately, Sard provides an excellent opportunity to get rid of this bag-gage. As previously mentioned, the for-each loop was removed for being a (verysimple) closure. Using similar logic, the do-while- and for-loops where removed.The for-loop is only really applicable to arrays, which are not as important inSard. And most of the imperative loops are intended to be rarely used, hencethe removal of the somewhat specialized do-while. While-loops however whereretained, to simplify highly imperative loops when or if they occur.

2.25 Checked Exceptions

Checked exceptions are a Java feature where one may force the caller of certainmethods to check for exceptions. While this helps moderately with type-safety,the cost of having a try-catch block at every call site is frankly unacceptable.Additionally, Scala and other ML-related languages have a much better way ofmodeling this called Either types. Here exemplified in Sard source code.

1 sealed trait Either [A,B]class Le f t [A] ( val l e f t :A) with Either [A, Nothing ]

3 class Right [B ] ( val r i g h t :B) with Either [ Nothing ,B]

Page 28: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

20 Chapter 2. Feature Set

Using this, one could represent checked exceptions by returning an Eitherfrom ones method, representing success as Right and failure as Left. Like so:

1 def f a i l I fOdd (x : Int ) : E i ther [ Str ing , S t r ing ] =i f ( x % 2 != 0) {

3 Le f t ( ”The i n t e g e r was odd ! ” )} else {

5 Right ( ”The i n t e g e r was even . ” )}

7/∗

9 I d id not de f i ne i s L e f t below ,but i t s behav ior shou ld be obv ious

11 ∗/i f ( f a i l I fOdd (3) . i s L e f t ) throw new Exception

Thus, one is forced to check the return value of the method if one wants touse it. This avoids an extra feature, and is also less verbose.

2.26 Switch Instructions

The switch instruction is present in Java. It is however redundant when thefull might of pattern matching is present, for which the switch instruction isonly the most trivial sub-case.

2.27 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 could not have been implemented in a library. On the otherhand, there are a number of reasons why it should not have been done thatway.

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 or CSV?

Page 29: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

2.28. Tail-Call Optimization 21

Then again, XML-literals may make it easier to work with XML. But thiswas not a problem that needed solving. XML is one of many serializationformats. And many have argued that XML is one of the least preferable ones[Atwood(2008)][Browne(2003)]. In summary, the best course of action wouldbe to limit any XML parsing to libraries.

2.28 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 an optimizationwhich makes sure that no function call that ends on another function callconsumes stack space. As such, one can recurse forever instead of just until thecall stack is full. Fortunately, TCO is already present in .NET, so no additionalwork from me is necessary.

2.29 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 are not compatible with static verification; None of theseare checked until runtime, and even then only by reflection. I would thereforeadvocate replacing annotations with regular documentation.

2.30 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 avoidingpublic 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:

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

}4

// These two expre s s i ons are e qu i v a l en t .

Page 30: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

22 Chapter 2. Feature Set

6 new Foo . foo = 5new 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.31 Symbols

A symbol is a interned string. Meaning that two symbols with the same namewill always refer to the same object.

1 valexampleMap = 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, no compelling reason has been offered why one could not have stuckwith strings instead.

2.32 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 onlya List[T] is considered a subtype of List[T]. This is the behavior present inJava. In covariant subtyping, List[A] is a subtype of List[T] if and only if A isa subtype of T. In contravariant subtyping, it is the other way around; List[A]is a subtype of List[T] if and only if 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]

Note that each type parameter of a class has its own variance behavior. Soit 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

Page 31: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

2.33. Multi-Line Strings 23

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, Javas design team decided that all classtype parameters should be invariant. A solution which can only be describedas somewhat drastic. Scala solved this much more elegantly by letting theprogrammer control variance.

2.33 Multi-Line Strings

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

2.34 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, in order 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 ones arguments in spite ofthis existing. In summary, the author is slightly in disfavor of implementingthis feature.

2.35 Optional Dynamic Typing

One of the more important reasons it was decided to create Sard is Scalas recentintroduction of dynamic typing. The new version of Java, 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.

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 the

Page 32: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

24 Chapter 2. Feature Set

ability to detect bugs automatically. There are no convincing arguments onwhy one would not want that.

2.36 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 [ ]

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, one can then define variablesof type B. If B had some known supertype, one could invoke methods on Bstoo. An existential type however is not bound to a name, and so cannot bemanipulated in any such interesting ways. It is mostly useful when the type inquestion is irrelevant. However, any existential type can, as the above exampleshows, be replaced with a regular type parameter. This leads one to believethat there is little benefit to keeping them.

2.37 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, one can see that self-type annotations enables oneto leave some subtyping abstract, thus defining the exact inheritances later.However, this concept has a considerable overlap with abstract inheritance, tothe point that its difficult to justify having it as a separate feature.

2.38 Higher-Kinded Generics

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

Page 33: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

2.39. Implicit Parameters and Conversions 25

parameters.

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:

1 /∗This t r a i t t a ke 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/∗

11 This i s an ins tance o f a Functor whereF == Li s t and fmap == map.

13 ∗/trait L i s t [+Elem ] with Functor [ L i s t [ Elem ] ] {

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

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.39 Implicit Parameters and Conversions

Implicit parameters, being a somewhat advanced topic, is hard to give simpleexamples of. If the reader does not already know what implicit parametersare, please refer to ”Programming Scala” [Wampler(2008)], which does a muchbetter job of explaining them . Martin Odersky also goes into quite somedepth discussing their correspondence with Haskell type classes in this paper[Odersky(2007b)].

As for the authors views on implicit parameters: Haskell Type classes whereoriginally introduced as a way of representing ad-hoc polymorphism in func-tional languages [Philip Wadler(1989)]. Hence most of the terminology aroundtype classes; The choice of terms like ”class” and ”instance” is not a coinci-dence - they where representing object-oriented programming! In a languagelike Sard, which already has a class system, the utility of type classes is dimin-ished.

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.

Page 34: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

26 Chapter 2. Feature Set

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.

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:

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 be 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 should not even be an op-portunity to have such a gratuitously large scope in the first place.

Page 35: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

Chapter 3

Syntax

In this chapter, the syntax of Sard is presented, and compared to that of Scalawhere interesting. The reader is assumed to be familiar with Scalas existingsyntax [Odersky(2009)], as well as Extended Backus-Naur Form notation forsyntax.

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 Scalas syntax that were not accompanied by any features being removed.These are discussed here.

3.1.1 New Closure Syntax

The syntax for creating and using closures have received several changes inSard. While Scalas underscore closures remain unchanged, the regular closureshave a new syntax. Scalas syntax is an argument list for the closure, followedby a left arrow, then an expression. Sards 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 more appealing to the author.

Scalas 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 ) ; } )

Sards 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: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

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.

Scalas syntax:

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

Sards 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 objects 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 is listed and briefly discussed. Familiar-ity with Extended Backus-Naur form is a must. Most of this section is notnecessary to understanding of the thesis, and may be skipped by the reader.

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 .∗)

Page 37: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

3.2. Syntax Specification 29

19 FileMember =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 ] ;

29I 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 onecan 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 =

Page 38: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

30 Chapter 3. Syntax

”(”Types ”) ” {”=>” AType} |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 ] ;

Page 39: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

3.2. Syntax Specification 31

Block I f = Block [ El se ] ;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 (∗

Page 40: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

32 Chapter 3. Syntax

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 ,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 [”=”] | ”&&” | ” | | ” |”<” | ”>” | ”<=” | ”>=” | ”==” | ”!=”;

241

Page 41: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

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 d

with ”=”. That ’ s a shorthand f o r ” Id = Id BinaryOp Expr ” .245 ∗)

Equa l sSu f f i xab l e =247 ”+” | ”−” | ”∗” | ”/” | ”ˆ” | ” |” |

”&” | ”>>” | ”>>>” | ”<<” | ”%” ;249

UnaryOp = ”−” | ”˜” | ” !” ;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: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

34 Chapter 3. Syntax

Page 43: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

Chapter 4

Type System

The type system of Sard may largely be assumed to work as per the Scalaspecification [Odersky(2009)]. There are two exceptions to this principle: Anumber of Scalas features have been removed, and the set of primitive typeshave changed quite a bit. We already discussed the first point in chapter one.Now its time to detail Sards primitive type hierarchy.

There are a number of reasons why a new set of primitive types for Sardwhere created. The most important one being that Scala has a set of primitivetypes borrowed 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 its 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, all special types, primitive types and primitive traits aredescribed.

35

Page 44: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

36 Chapter 4. Type System

4.1 Special Types

There are two ”special” types in the type system. They are special by virtueof them being a top and bottom type respectively. That is, one is a supertypeof all types, and one is a subtype of all types.

4.1.1 trait Any

Any is Sards 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.

1 // Checks i f the r e c e i v i n g o b j e c t i s an ins tance o f T.sealed def isA [T ] : Bool

3/∗

5 Casts the r e c e i v i n g o b j e c t to type T, re turns thecas ted re f e r ence . Fa i l s wi th RefutedPattern i f

7 the r e c e i v i n g o b j e c t i s not a T. Exact ly e qu i v a l en tto pa t t e rn matching t ha t j u s t reb inds the argument .

9 ∗/sealed def asA [T ] :T =

11 match( this ) {case T as x => x

13 }

15 // Checks r e f e r ence ( in ) e q u a l i t y between two Any .sealed def eq ( that :Any) : Bool

17 sealed def neq ( that :Any) : Bool = ! eq ( that )

19 /∗I s c a l l e d be f o r e o b j e c t i s garbage c o l l e c t e d .

21 Does nothing by d e f a u l t . I s t he re f o r use by o b j e c t swhich a l l o c a t e resources o ther than memory .

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

4.1.2 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.

Page 45: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

4.2. Primitive Traits 37

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 Cloneable[A]

An interface for mutable classes that may be copied. May be a shallow or deepcopy depending on implementation.

def c l one :A

4.2.2 trait Showable

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

1 def show : S t r ing

4.2.3 trait Binary

Binary, similarly to Showable, is trait for things which may be turned into abyte-string.

1 def bytes : Array [ Byte ]

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.

1 def equa l s ( that :A) : Boolsealed def ==(that :A) : Bool = this . equa l s ( that )

3 sealed def !=( that :A) : Bool = ! ( this == that )

4.2.5 trait Hashable

Hashable types can be turned into a unsigned 32-bit hash code. If this is also asubclass of Equality, hashCode should be implemented in such a way that this== that logically implies this.hashCode == that.hashCode.

1 def hashCode : UInt

Page 46: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

38 Chapter 4. Type System

4.2.6 trait Ordered[A]

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

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

3sealed def >( that :A) : Bool = this . compare ( that ) == Greater

5 sealed def <( that :A) : Bool = this . compare ( that ) == Lesssealed def <=(that :A) : Bool = ! ( this > that )

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

9 sealed def min( that :A) :A = i f ( this <= that ) this else thatsealed def max( that :A) :A = i f ( this >= that ) this else that

4.2.7 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.8 trait Exception

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

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

4.2.9 trait Numeric[A]

Numeric[A] is a type which is a number.

def abs :A2 def s i gn :A

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

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

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

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

Page 47: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

4.2. Primitive Traits 39

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

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 toFloat : 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 the functionality of this class.

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 ra ( that )

Page 48: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

40 Chapter 4. Type System

def s ra ( shamt : Byte ) :A13 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

4.2.15 trait FunctionN[-A,-B,-C..,-N,+R]

The various function classes. For brevity, they have here been listed in seriesnotation up to N, but the general pattern should be obvious. For some N,there are first N contravariant input parameters followed by a covariant outputparameter.

FunctionN types are defined between N=0(i.e no input parameter, just anoutput parameter) up to N=8.

def apply ( a :A, b :B, c :C . . . n :N) :R

4.2.16 trait Lazy[+A]

A lazily evaluated value. For more on this see ”Call-by-need” under the featureset chapter.

Implemented traits: Function0[A]

4.2.17 trait PartialFunction[-A,+B]

A Function1 which is only defined occasionally for its arguments. One can askthis function if its defined for some value.

Implemented Traits: Function1[A]

1 def i sDe f inedAt ( a :A) : Bool

Page 49: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

4.3. Primitive Types 41

4.2.18 trait Updateable[+K,+V]

This is a trait for mutable arrays or tables. For more information see ”SyntacticSugar for Array/Table Mutation” earlier in the paper.

Implemented Traits: PartialFunction[K,V]

1 def update (k :K, v :V) : Unit

4.3 Primitive Types

These are concrete primitive types. To save the time of author and readerthe implementation of their traits is not specified. In any case most of thoseoperations to be implemented are not illustratable in Sard source code. It isalso generally obvious how they should be implemented. Most of this sectionis not necessary to understanding of the thesis, and may be skipped by thereader.

4.3.1 object System

System is an object containing some utility methods for the runtime system.

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

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

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

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

4.3.2 sealed trait Ordering

Ordering is an enumeration which tells of the ordering between two types thatimplement Ordered[A].

Implemented Traits:Equality[Ordering].

object Less with Ordering2 object Equal with Ordering

object Greater with Ordering

4.3.3 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: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

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.4 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// Temporarily suspends t h i s thread .

9 def yield : Unit// S ta r t s a s l e e p i n g thread .

11 def s t a r t : Unit// Forces t h i s thread to terminate .

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

4.3.5 class Array[Elem]

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

– Cloneable[Array[Elem]]

– Updateable[UInt,Elem]

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 .

4.3.6 class TupleN[+A,+B,..+N]

The various tuple classes. Are also defined for various number of parameterslike FunctionN. Is defined between N=2 and N=6.

1 def this ( 1 :A, 2 :B , . . , n :N)val 1 :A

3 val 2 :B. .

5 val n :N

Page 51: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

4.3. Primitive Types 43

4.3.7 sealed trait Bool

The common Boolean.Implemented Traits:

– Eq[Bool]

– Binary

– Showable

1 object True with Boolobject False with Bool

3 sealed def ! : Boolsealed def &&(that : Bool ) : Bool

5 sealed def | | ( that : Bool ) : Bool

4.3.8 class Char

A single Unicode character.Implemented Traits:

– Ordered[Char]

– Enumerable[Char]

– Showable

– 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 t e r 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

Page 52: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

44 Chapter 4. Type System

4.3.9 class String

An immutable Unicode string.Implemented Traits:

– Ordered[String]

– Enumerable[String]

– Showable

– Binary

– PartialFunction[UInt,Char]

/∗2 Cons t ruc t i b l e from va r i a b l e number o f characters ,

array o f characters ,4 another s t r i n g

∗/6 def this ( chars : Char ∗)

def this ( charArray : Array [ Char ] )8 def this ( that : S t r ing )

10 /∗Gets the S t r ing s l eng t h . ∗/def l ength : UInt

12/∗Converts S t r ing in to Array o f Char . ∗/

14 def toCharArray : Array [ Char ]

16 /∗Uppercases or lowercases s t r i n g . ∗/def toUpper : S t r ing

18 def toLower : S t r ing

20 /∗Prepends or appends another S t r ing to t h i s one . ∗/def prepend ( that : S t r ing ) : S t r ing

22 def append ( that : S t r ing ) : S t r ing

4.3.10 sealed trait UnicodeCategory

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

– Equality[UnicodeCategory]

– 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

Page 53: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

4.3. Primitive Types 45

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.11 class SByte

A signed 8-bit integer.Implemented Traits:

– Showable

– Binary

– Enumerable[SByte]

– Integral[SByte]

– NumberConvertible

– Bitwise[SByte]

– Ordered[SByte]

4.3.12 class Byte

An unsigned 8-bit integer.Implemented Traits:

– Showable

– Binary

Page 54: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

46 Chapter 4. Type System

– Enumerable[Byte]

– Integral[Byte]

– NumberConvertible

– Bitwise[Byte]

– Ordered[Byte]

4.3.13 class Short

A signed 16-bit integer.

Implemented Traits:

– Showable

– Binary

– Enumerable[Short]

– Integral[Short]

– NumberConvertible

– Bitwise[Short]

– Ordered[Short]

4.3.14 class UShort

An unsigned 16-bit integer.

Implemented Traits:

– Showable

– Binary

– Enumerable[UShort]

– Integral[UShort]

– NumberConvertible

– Bitwise[UShort]

– Ordered[UShort]

Page 55: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

4.3. Primitive Types 47

4.3.15 class Int

A signed 32-bit integer.Implemented Traits:

– Showable

– Binary

– Enumerable[Int]

– Integral[Int]

– NumberConvertible

– Bitwise[Int]

– Ordered[Int]

4.3.16 class UInt

An unsigned 32-bit integer.Implemented Traits:

– Showable

– Binary

– Enumerable[UInt]

– Integral[UInt]

– NumberConvertible

– Bitwise[UInt]

– Ordered[UInt]

4.3.17 class Long

A signed 64-bit integer.Implemented Traits:

– Showable

– Binary

– Enumerable[Long]

– Integral[Long]

– NumberConvertible

– Bitwise[Long]

– Ordered[Long]

Page 56: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

48 Chapter 4. Type System

4.3.18 class ULong

An unsigned 64-bit integer.Implemented Traits:

– Showable

– Binary

– Enumerable[ULong]

– Integral[ULong]

– NumberConvertible

– Bitwise[ULong]

– Ordered[ULong]

4.3.19 class Float

A 32-bit floating-point.Implemented Traits:

– Showable

– Binary

– Ordered[Float]

– Fractional[Float]

– NumberConvertible

– Floating[Float]

4.3.20 class Double

A 64-bit floating-point.Implemented Traits:

– Showable

– Binary

– Ordered[Double]

– Fractional[Double]

– NumberConvertible

– Floating[Double]

Page 57: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

4.3. Primitive Types 49

4.3.21 class LongDouble

A 128-bit floating-point.Implemented Traits:

– Showable

– Binary

– Ordered[LongDouble]

– Fractional[LongDouble]

– NumberConvertible

– Floating[LongDouble]

4.3.22 class IndexOutOfBounds

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

def this ( val idx : UInt )

4.3.23 class IndexUndefined

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

1 def this ( val idx : UInt )

4.3.24 class Overflow/class Underflow

Exceptions that tell of numerical over/underflow.

4.3.25 class DivideByZero

An exception that informs about division by zero.

4.3.26 class IllegalArgument

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

4.3.27 class OutOfMemory

An exception thrown when the VM runs out of memory.

4.3.28 class StackOverflow

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

Page 58: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

50 Chapter 4. Type System

4.3.29 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 59: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

Chapter 5

Conclusions

5.1 Acknowledgments

I wish to acknowledge several of the graduate students present at the seminarof Sards feature set. Johan Granberg pointed out that binding methods inpattern matching might be useful. Another person suggested removing singleinheritance. Unfortunately, the author was unable to get his name after theseminar.

5.2 Limitations

Originally, it was intended to make Sard significantly simpler than Scala. Thisis mostly not the case. While Sard is maybe slightly simpler than Scala onaccount of being more orthogonal, the feature sets of both languages are ap-proximately equally large.

Additionally, while removing calling compatibility to Java was necessary fora number of reasons, not having Javas libraries is certainly a disadvantage.

5.3 Alternate Solutions

There are some decisions made during the course of this thesis of which theauthor is somewhat unsure. Here is a short list of them, with motivation.

5.3.1 Keeping Higher-Ranked Generics

Regarding higher ranked types, they greatly aid the power of the type system.On the other hand, they can easily be used to write nigh-incomprehensiblecode. In a way, it boils down to a trade-off between readability and power.

51

Page 60: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

52 Chapter 5. Conclusions

5.3.2 Keeping Type Members

Type members on the other hand add no new functionality to the language. Infact, they can always be replaced with type parameters. However, in certaincases the parameterized version will be much more verbose. Whether thisjustifies their inclusion is debatable. On the other hand, type members areeasily understood as being slots that contain types, so they should not makethe language much harder to learn or use.

5.4 Conclusion

While removing the ideals of Scala from Java certainly has its disadvantages,overall the approach seems promising. A new language is about to enter com-puting, one which is expressive and safe. One hopes that in some time, manywill use this language to write nontrivial software.

Page 61: Sard: An Object-Functional Programming Language · Sard: An Object-Functional Programming Language Hugo Svallfors June 20, 2011 Master’s Thesis in Computing Science, ... are scrapped.

References

[Atwood(2008)] J. Atwood. Xml: The angle-bracket tax, 2008. URLhttp://www.codinghorror.com/blog/2008/05/xml-the-angle-bracket-tax.html.

[Browne(2003)] E. Browne. The myth of self-describing xml, 2003. URLhttp://www.superfrink.net/athenaeum/e2.pdf.

[Hoare(2009)] T. Hoare. Null references: The billion dollar mistake, 2009.

[Odersky(2006)] M. Odersky. The scala experiment, 2006. URLhttp://www.scala-lang.org/sites/default/files/odersky/google06.pdf.

[Odersky(2007a)] M. Odersky. The scala experience, 2007a. URLhttp://www.scala-lang.org/sites/default/files/odersky/pppj07.pdf.

[Odersky(2007b)] M. Odersky. Poor man’s type classes, 2007b. URLhttp://www.scala-lang.org/sites/default/files/odersky/wg2.8-boston06.pdf.

[Odersky(2009)] M. Odersky. The Scala Language Specification - Version 2.8. EPFL,2009.

[Philip Wadler(1989)] S. B. Philip Wadler. How to make ad-hoc polymorphism lessad-hoc, 1989.

[Wampler(2008)] D. Wampler. Programming Scala. O’Reilly Media, 2008. URLhttp://programming-scala.labs.oreilly.com/.

53