Olej писал(а):
Следующий вариант - это чисто функциональные языки.
Первый из них - Scheme.
Следующий вариант:
Scala.
Scala — мультипарадигмальный язык программирования, спроектированный кратким и типобезопасным для простого и быстрого создания компонентного программного обеспечения. Мультипарадигмный потому, что сочетает в себе возможности функционального и объектно-ориентированного программирования. Первые версии языка созданы в 2003 году коллективом лаборатории методов программирования Федеральной политехнической школы Лозанны под руководством Мартина Одерски.
Язык новый, из последних (2003). Ноги растут из Java: Scala должен упростить то, что на Java сложно. Характерно, что многие считают Scala дальнейшим расширением языка Java и даже называют его как Java++. Хотя синтаксис
радикально различается. Но при всём том, в Scala код можно
импортировать весь API из Java JDK, все пакеты: хотите - пишите на Scala, хотите - вызывайте их Java.
О установке Scala уже сказано пару слов в теме:
Scala.
Расширения имён файлов (сценариев) Scala: .scb, .scala. Scala отходит от принятое в Java соглашения соответствия имён классов содержащих им файлов: не требует в названии файла, содержащего определение класса, отражать имя этого класса.
Пример реализации всё того же приложения (параметры произвольного многоугольника):
Код: Выделить всё
import scala.math._ /* символ _ в Scala - "групповой" символ */
import java.util.StringTokenizer
class Complex( re: Double, im: Double ) extends AnyRef {
private val r: Double = re
private val i: Double = im
def -(that: Complex) =
new Complex( r - that.r, i - that.i )
def real: Double = r
def imag: Double = i
override def toString = "[%.2f,%.2f] ".format( r, i )
def abs(): Double = sqrt( r * r + i * i )
def arg(): Double = atan2( i, r )
}
object triangle {
def perimeter( l: List[ Complex ] ): Double = {
val h: Complex = l.head
def distance( p1: Complex, p2: Complex ): Double = ( p1 - p2 ).abs()
def sides( l: List[ Complex ] ): Double = {
if( Nil == l.tail ) distance( l.head, h )
else distance( l.head, l.tail.head ) + sides( l.tail )
}
sides( l )
}
def square( l: List[ Complex ] ): Double = {
val h: Complex = l.head
def trisq( l: List[ Complex ] ): Double = {
val s1 = l.head - h
val s2 = l.tail.head - h
s1.abs * s2.abs * abs( sin( s1.arg - s2.arg ) ) / 2.0
}
def addsq( l: List[ Complex ] ): Double = {
if( Nil == l.tail ) 0.0
else trisq( l ) + addsq( l.tail )
}
addsq( l.tail )
}
def next(): Unit = {
Console.println( "координаты вершин в формате: X Y (^D конец ввода)" )
var i: Int = 0
var eof: Boolean = false
var shape: List[ Complex ] = List()
while( !eof ) {
var s: String = Console.readLine( "%s%d%s", "вершина № ", i + 1, " : " )
if( null == s ) {
eof = true // ^D - конец ввода
Console.print( "\r" )
}
else { // в блоке используется Java API:
try {
val st: StringTokenizer = new StringTokenizer( s, " \r\n" )
var x: Double = st.nextElement.toString.toDouble
var y: Double = st.nextElement.toString.toDouble
try { // попытка чтения сверх x, y
if( null != st.nextElement.toString )
throw new Exception( "Сгенерированное исключения" )
}
catch {
case ex: NoSuchElementException =>
shape = new Complex( x, y ) :: shape
i = i + 1
}
}
catch { // все! ошибки ловятся здесь
case ex: Exception =>
Console.println( "ошибка ввода!" )
}
}
}
Console.print( "вершин " + shape.length + " : " )
shape.map( x => Console.print( x ) )
Console.println
Console.println( "периметр = %.2f".format( perimeter( shape ) ) )
Console.println( "площадь = %.2f".format( square( shape ) ) )
Console.println( "---------------------------------" )
next()
}
def main( args: Array[ String ] ): Unit = next() // главная стартовая подпрограмма
}
Код Scala, конечно, приятный: вся гибкость без ограничений функциональных языков, но без привязки к чистой функционаьности, без принуждения, без фанатизма.
В этом образце кода есть и классы-объекты, и функции как объекты данных (функционалное программирование), показана и обработка исключений (даже структурированная обработка исключений). Специально показано (StringTokenizer), как Scala может использовать все возможности Java API (). Ниаких проблем с русским и UTF-8 - всё работает "ис каробки", что значит новый язык.
Созданное приложение нужно откомпилировать в файлы клвссов (*.class). Компиляция Scala происходит до неприятного долго (в сравнении с Java, например):
Код: Выделить всё
$ scalac triangle.scala
$ ls *.class
Complex.class triangle$$anonfun$next$1.class triangle.class triangle$.class
Выполнение:
Код: Выделить всё
$ scala triangle
координаты вершин в формате: X Y (^D конец ввода)
вершина № 1 : 1 1
вершина № 2 : 1 2
вершина № 3 : 2 1
вершин 3 : [2.00,1.00] [1.00,2.00] [1.00,1.00]
периметр = 3.41
площадь = 0.5
0
---------------------------------
координаты вершин в формате: X Y (^D конец ввода)
вершина № 1 : 1 1
вершина № 2 : 1 2
вершина № 3 : 2 2
вершина № 4 : 2 1
вершин 4 : [2.00,1.00] [2.00,2.00] [1.00,2.00] [1.00,1.00]
периметр = 4.0
0
площадь = 1.0
0
---------------------------------
координаты вершин в формате: X Y (^D конец ввода)
вершина № 1 : 0 0
вершина № 2 : 0 1
вершина № 3 : 3 1
вершина № 4 : 3 0
вершин 4 : [3.00,0.00] [3.00,1.00] [0.00,1.00] [0.00,0.00]
периметр = 8.0
0
площадь = 3.0
0
---------------------------------
координаты вершин в формате: X Y (^D конец ввода)
вершина № 1 : ^C
Вот как срабатывает обработка исключений:
Код: Выделить всё
$ scala triangle
вершина № 1 : 4 а
ошибка ввода!
вершина № 1 : 1 2 3
ошибка ввода!
вершина № 1 : 3ю5 2
ошибка ввода!
вершина № 1 :
ошибка ввода!
вершина № 1 : 1
ошибка ввода!
вершина № 1 : ^C