Skip to content

Commit 81c019c

Browse files
committed
Added regular expresison patterns to tour
1 parent c95c67b commit 81c019c

5 files changed

+169
-3
lines changed

tour/automatic-closures.md

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
layout: overview
3+
title: Automatic Type-Dependent Closure Construction
4+
---
5+
6+
Scala allows parameterless function names as parameters of methods. When such a method is called, the actual parameters for parameterless function names are not evaluated and a nullary function is passed instead which encapsulates the computation of the corresponding parameter (so-called *call-by-name* evalutation).
7+
8+
The following code demonstrates this mechanism:
9+
10+
object TargetTest1 extends Application {
11+
def whileLoop(cond: => Boolean)(body: => Unit): Unit =
12+
if (cond) {
13+
body
14+
whileLoop(cond)(body)
15+
}
16+
var i = 10
17+
whileLoop (i > 0) {
18+
println(i)
19+
i -= 1
20+
}
21+
}
22+
23+
The function whileLoop takes two parameters `cond` and `body`. When the function is applied, the actual parameters do not get evaluated. But whenever the formal parameters are used in the body of `whileLoop`, the implicitly created nullary functions will be evaluated instead. Thus, our method `whileLoop` implements a Java-like while-loop with a recursive implementation scheme.
24+
25+
We can combine the use of [infix/postfix operators](operators.html) with this mechanism to create more complex statements (with a nice syntax).
26+
27+
Here is the implementation of a loop-unless statement:
28+
29+
object TargetTest2 extends Application {
30+
def loop(body: => Unit): LoopUnlessCond =
31+
new LoopUnlessCond(body)
32+
protected class LoopUnlessCond(body: => Unit) {
33+
def unless(cond: => Boolean) {
34+
body
35+
if (!cond) unless(cond)
36+
}
37+
}
38+
var i = 10
39+
loop {
40+
println("i = " + i)
41+
i -= 1
42+
} unless (i == 0)
43+
}
44+
The `loop` function just accepts a body of a loop and returns an instance of class `LoopUnlessCond` (which encapsulates this body object). Note that the body didn't get evaluated yet. Class `LoopUnlessCond` has a method `unless` which we can use as a *infix operator*. This way, we achieve a quite natural syntax for our new loop: `loop { < stats > } unless ( < cond > )`.
45+
46+
Here's the output when `TargetTest2` gets executed:
47+
48+
i = 10
49+
i = 9
50+
i = 8
51+
i = 7
52+
i = 6
53+
i = 5
54+
i = 4
55+
i = 3
56+
i = 2
57+
i = 1
58+

tour/index.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Scala is a pure object-oriented language in the sense that [every value is an ob
1111
## Scala is functional ##
1212
Scala is also a functional language in the sense that [every function is a value](unified_types.html). Scala provides a [lightweight syntax](anonymous-function-syntax.html) for defining anonymous functions, it supports [higher-order functions](higher-order-functions.html), it allows functions to be [nested](nested-functions.html), and supports [currying](currying.html). Scala's [case classes](case-classes.html) and its built-in support for [pattern matching](pattern-matching.html) model algebraic types used in many functional programming languages.
1313

14-
Furthermore, Scala's notion of pattern matching naturally extends to the processing of XML data with the help of right-ignoring sequence patterns. In this context, sequence comprehensions are useful for formulating queries. These features make Scala ideal for developing applications like web services.
14+
Furthermore, Scala's notion of pattern matching naturally extends to the processing of XML data with the help of (right-ignoring sequence patterns)[regular-expression-patterns.html]. In this context, [sequence comprehensions](sequence-comprehensions.html) are useful for formulating queries. These features make Scala ideal for developing applications like web services.
1515

1616
## Scala is statically typed ##
1717
Scala is equipped with an expressive type system that enforces statically that abstractions are used in a safe and coherent manner. In particular, the type system supports:
@@ -29,8 +29,8 @@ A [local type inference mechanism](local-type-inference.html) takes care that th
2929
## Scala is extensible ##
3030

3131
In practice, the development of domain-specific applications often requires domain-specific language extensions. Scala provides a unique combination of language mechanisms that make it easy to smoothly add new language constructs in form of libraries:
32-
* any method may be used as an infix or postfix operator
33-
* closures are constructed automatically depending on the expected type (target typing).
32+
* any method may be used as an [infix or postfix operator](operators.html)
33+
* [closures are constructed automatically depending on the expected type](automatic-closures.html) (target typing).
3434

3535
A joint use of both features facilitates the definition of new statements without extending the syntax and without using macro-like meta-programming facilities.
3636
Scala interoperates with Java and .NET

tour/operators.md

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
layout: overview
3+
title: Operators
4+
---
5+
6+
Any method which takes a single parameter can be used as an *infix operator* in Scala. Here is the definition of class `MyBool` which defines three methods `and`, `or`, and `negate`.
7+
8+
class MyBool(x: Boolean) {
9+
def and(that: MyBool): MyBool = if (x) that else this
10+
def or(that: MyBool): MyBool = if (x) this else that
11+
def negate: MyBool = new MyBool(!x)
12+
}
13+
14+
It is now possible to use `and` and `or` as infix operators:
15+
16+
def not(x: MyBool) = x negate; // semicolon required here
17+
def xor(x: MyBool, y: MyBool) = (x or y) and not(x and y)
18+
19+
As the first line of this code shows, it is also possible to use nullary methods as postfix operators. The second line defines an xor function using the and and or methods as well as the new `not` function. In this example the use of _infix operators_ helps to make the definition of `xor` more readable.
20+
21+
Here is the corresponding code in a more traditional object-oriented programming language syntax:
22+
23+
def not(x: MyBool) = x.negate; // semicolon required here
24+
def xor(x: MyBool, y: MyBool) = x.or(y).and(x.and(y).negate)

tour/regular-expression-patterns.md

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
layout: overview
3+
title: Regular Expression Patterns
4+
---
5+
6+
## Right-ignoring sequence patterns ##
7+
8+
Right-ignoring patterns are a useful feature to decompose any data which is either a subtype of Seq[A] or a case class with an iterated formal parameter, like for instance
9+
10+
Elem(prefix:String, label:String, attrs:MetaData, scp:NamespaceBinding, children:Node*)
11+
12+
In those cases, Scala allows patterns having a wildcard-star `_*` in the rightmost position to stand for arbitrary long sequences.
13+
The following example demostrate a pattern match which matches a prefix of a sequence and binds the rest to the variable `rest`.
14+
15+
object RegExpTest1 extends Application {
16+
def containsScala(x: String): Boolean = {
17+
val z: Seq[Char] = x
18+
z match {
19+
case Seq('s','c','a','l','a', rest @ _*) =>
20+
println("rest is "+rest)
21+
true
22+
case Seq(_*) =>
23+
false
24+
}
25+
}
26+
}
27+
28+
In contrast to previous Scala version, it is no longer allowed to have arbitrary regular expressions, for the reasons described below.
29+
General `RegExp` patterns temporarily retracted from Scala
30+
31+
Since we discovered a problem in correctness, this feature is temporarily retracted from the Scala language. If there is request from the user community, we might reactivate it in an improved form.
32+
33+
According to our opinion regular expressions patterns were not so useful for XML processing as we estimated. In real life XML processing applications, XPath seems a far better option. When we discovered that our translation or regular expressions patterns has some bugs for esoteric patterns which are unusual yet hard to exclude, we chose it would be time to simplify the language.

tour/sequence-comprehensions.md

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
layout: overview
3+
title: Sequence Comprehensions
4+
---
5+
6+
Scala offers a lightweight notation for expressing *sequence comprehensions*. Comprehensions have the form `for (enumerators) yield e`, where `enumerators` refers to a semicolon-separated list of enumerators. An *enumerator* is either a generator which introduces new variables, or it is a filter. A comprehension evaluates the body `e` for each binding generated by the enumerators and returns a sequence of these values.
7+
8+
Here is an example:
9+
10+
object ComprehensionTest1 extends Application {
11+
def even(from: Int, to: Int): List[Int] =
12+
for (i <- List.range(from, to) if i % 2 == 0) yield i
13+
Console.println(even(0, 20))
14+
}
15+
16+
The for-expression in function introduces a new variable `i` of type `Int` which is subsequently bound to all values of the list `List(from, from + 1, ..., to - 1)`. The guard `if i % 2 == 0` filters out all odd numbers so that the body (which only consists of the expression i) is only evaluated for even numbers. Consequently, the whole for-expression returns a list of even numbers.
17+
18+
The program yields the following output:
19+
20+
List(0, 2, 4, 6, 8, 10, 12, 14, 16, 18)
21+
22+
Here is a more complicated example which computes all pairs of numbers between `0` and `n-1` whose sum is equal to a given value `v`:
23+
24+
object ComprehensionTest2 extends Application {
25+
def foo(n: Int, v: Int) =
26+
for (i <- 0 until n;
27+
j <- i + 1 until n if i + j == v) yield
28+
Pair(i, j);
29+
foo(20, 32) foreach {
30+
case (i, j) =>
31+
println("(" + i + ", " + j + ")")
32+
}
33+
}
34+
35+
This example shows that comprehensions are not restricted to lists. The previous program uses iterators instead. Every datatype that supports the operations `filterWith`, `map`, and `flatMap` (with the proper types) can be used in sequence comprehensions.
36+
37+
Here's the output of the program:
38+
39+
(13, 19)
40+
(14, 18)
41+
(15, 17)
42+
43+
There is also a special form of sequence comprehension which returns `Unit`. Here the bindings that are created from the list of generators and filters are used to perform side-effects. The programmer has to omit the keyword `yield` to make use of such a sequence comprehension.
44+
Here's a program which is equivalent to the previous one but uses the special for comprehension returning `Unit`:
45+
46+
object ComprehensionTest3 extends Application {
47+
for (i <- Iterator.range(0, 20);
48+
j <- Iterator.range(i + 1, 20) if i + j == 32)
49+
println("(" + i + ", " + j + ")")
50+
}
51+

0 commit comments

Comments
 (0)