Skip to content

Instantly share code, notes, and snippets.

@shajra-cs
Created September 28, 2015 00:35
Show Gist options
  • Save shajra-cs/ab0a00dae047a843d4af to your computer and use it in GitHub Desktop.
Save shajra-cs/ab0a00dae047a843d4af to your computer and use it in GitHub Desktop.
Here's an example of a tutorial that spun out of a Friday discussion.
package c12e.learn
// Note, expressions in Scala need to be inside things like objects. We'll
// discuss objects (and packages) later. These are just a complications we
// introduce now to have a well-formed program.
object ValuesAndTypes {
// Binding Values
// --------------
// Let's bind some values to names using Scala's *val* syntax. This is a
// basis of writing programs. Note that "values" and "expressions" are
// synonyms, and both terms are commonly used interchangeably.
val i: Int = 13: Int
val s: String = "Hello": String
val b: Boolean = true: Boolean
// Scala gives us some *literals* to write down some basic values. Every
// value has a type. Integers are represented in Scala by the Int type, with
// values are written as you might expect. Text is represented by the String
// type with value written as the text enclosed by double quotes. There is
// also a type with two values -- true and false -- called Boolean, which is
// important for branching.
//
// We use a colon to explicitly *ascribe* a value with its type.
//
// Above, we've bound the value 13 of type Int to the name "i" that is
// restricted to bindings of only Ints. Similarly, we've bound the value
// "Hello" of type String to the name "s" that's limited to bindings of only
// Strings.
// Tuple Literals
// --------------
// Tuples can group values of different types together. Scala also gives us
// a tuple literal notation that uses parentheses, a lot like coordinates:
val pair: (Int, String) =
(1: Int, "a": String): (Int, String)
val triple: (Int, String, Boolean) =
(2: Int, "b": String, false: Boolean): (Int, String, Boolean)
// The *arity* of a tuple indicates how many types it groups together.
// 2-tuples are tuples of arity 2, 3-tuples of arity 3, and so forth.
// 2-tuples are often called *pairs*. Another term for tuple is *product*.
// Type Inference
// --------------
// There is a *type theoretic* view of values that's founded on the idea that
// values can only have one type. If this is the case, then we know that 13
// is an Int without saying so explicitly. Similarly we know that "Hello" is
// a String.
//
// We don't have to ascribe our values with their respective types:
val i2: Int = 13
val s2: String = "Hello"
val b2: Boolean = true
val pair2: (Int, String) = (1, "a")
val triple2: (Int, String, Boolean) = (2, "b", false)
// Note, that we used new names (i2, s2, pair2, and triple2) because old
// names can not be rebound. This is very much like how in mathematics, π
// can not be rebound to anything other than the number 3.1415...
// Furthermore, we also don't have to ascribe the bindings:
val i3 = 13
val s3 = "Hello"
val b3 = true
val pair3 = (1, "a")
val triple3 = (2, "b", false)
// In Scala, we try to avoid ascribing values whereever we can, but we often
// ascribe bindings to document our intent to others. The type is like a
// contract to the outside world, so they don't have to read the
// implementation of the value (which can be expressions far more complex
// than just 13 or "Hello").
// Complexity with Inference
// -------------------------
// Type inference would be easy if Scala were purely type theoretic where
// values indeed only have one type. Scala, though, takes a more *set
// theoretic* view that values can have multiple types. Think of a Venn
// diagram of sets, where values are like elements that lie in the
// intersections of different sets.
// The common justification for this decision is to have compatibility with
// Scala's sister programming language Java (Scala's popularity is in large
// part due to it's interoperability with Java).
// In Scala, types have a hierarchy. At the top of the hierarchy, we have
// one type, Any, that is so generic that every value is of this type from
// numbers like 13 to text like "Hello". This is why in Scala, we can do
// this:
val i4: Any = 13
val s4: Any = "Hello"
val b4: Any = true
val pair4: Any = (1, "a")
val triple4: Any = (2, "b", false)
// We say that all types are a *subtype* of Any, because we can use instances
// of any type as an Any. We can also say that Any is the *supertype* of all
// types.
// There is also an interesting "bottom" type of the hierarchy called Nothing
// that has no values, and is the subtype of all types. Because Nothing has
// no values, we don't use it often.
// Because Scala is more set theoretic than type theoretic, we can sometimes
// have problems with inference. Most of the time, Scala infers the type
// we'd intend from a type theoretic viewpoint. But sometimes it infers an
// Any or Nothing, which is generally not our intent. This is another reason
// we ascribe bindings in Scala.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment