сравнение языков программирования

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: сравнение языков программирования

Непрочитанное сообщение Olej » 14 фев 2014, 21:56

Olej писал(а): В частности, из чисто компилирующих языков, например, - Go.
Про Go : где взять, как установить ... и, самое главное: ссылки на описания, учебники, ресурсы и справочники, которых более чем достаточно, чтобы уверенно писать на Go см. в теме: Go.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

сравнение языков программирования

Непрочитанное сообщение Olej » 14 фев 2014, 22:07

Olej писал(а): Про Go : где взять, как установить ... и, самое главное: ссылки на описания, учебники, ресурсы и справочники, которых более чем достаточно, чтобы уверенно писать на Go см. в теме: Go.
А теперь, дети, я расскажу вам волшебную сказку ... :lol: ... : вариант всё той же нашей задачи на языке Go:

Код: Выделить всё

package main
 
import (
   "fmt";  "os";  "io"; "errors"
   "strings"; "strconv"; "math"; "math/cmplx"
)

// -------------- класс точки вершины ---------------------
type point struct {                    
   xy complex128
}
func (p *point) String() string {                       // формат вывода
   return fmt.Sprintf( "[%.2f,%.2f] ", real( p.xy ), imag( p.xy ) )
}
func (p *point) inpoint() ( ok bool, err error ) {      // ввод координат
   buf := make( [] byte, 1024 )
   ok = false
   n, err := os.Stdin.Read( buf )
   if err == io.EOF || n == 0 || buf[ n - 1 ] != '\n' { // конец ввода
      err = io.EOF 
      return
   }  
   as := strings.Split( string( buf[ : n - 1 ] ), string( " " ) )
   if len( as ) != 2 {
      err = errors.New( "число параметров" )
      return
   }
   x, err := strconv.ParseFloat( as[ 0 ], 64 )
   if err != nil { return }                             // ошибка преобразования
   y, err := strconv.ParseFloat( as[ 1 ], 64 )
   if err != nil { return }                             // ошибка преобразования 
   p.xy = complex( x, y )
   ok, err = true, nil
   return 
}

// ------------- класс многоугольника ---------------------
type shape []point
func ( p *shape ) append( data point ) {
   slice := *p
   l := len( slice )
   if l + 1 > cap( slice ) {                      // недостаточно места
      newSlice := make( [] point, ( l + 1 ) * 2 ) // выделение вдвое большего буфера
      if l > 0 {                                  // скопировать данные
         for i, c := range slice { newSlice[ i ] = c }
      }
      slice = newSlice 
   }
   slice = slice[ 0 : l + 1 ]
   slice[ l ] = data 
   *p = slice;
}
func ( p *shape ) String() string {               // формат вывода
   slice := *p
   var s string = ""
   for _, c := range slice {  s += c.String() }
   return s
}
func ( p *shape ) perimeter() float64 {
   summa := 0.0
   slice := *p
   for i, c := range slice { 
      if i == 0 {
         summa += cmplx.Abs( c.xy - slice[ len( slice ) - 1 ].xy )
      } else {
         summa += cmplx.Abs( c.xy - slice[ i - 1 ].xy )
      }
   }
   return summa
}
func ( p *shape ) square() float64 {
   summa := 0.0
   slice := *p
   for i := 0; i < len( slice ) - 2; i++ {
      r1, θ1 := cmplx.Polar( slice[ i + 1 ].xy - slice[ 0 ].xy ) 
      r2, θ2 := cmplx.Polar( slice[ i + 2 ].xy - slice[ 0 ].xy ) 
      summa += r1 * r2 * math.Abs( math.Sin( θ2 - θ1 ) ) / 2.
   }
   return summa
}

func main() {
   for {
      fmt.Println( "координаты вершин в формате: X Y" )
      многоугольник := new( shape )
      i := 0
      точка := new( point ) 
      for {
         fmt.Printf( "вершина № %v: ", i + 1 )
         ok, err := точка.inpoint()                        // ввод координат вершины
         if !ok { 
            if err == io.EOF { fmt.Printf( "\r" ); break } // конец ввода вершин
            fmt.Printf( "ошибка ввода: %s!\n", err )
            continue
         }
         многоугольник.append( *точка )
         i++
      }
      fmt.Printf( "вершин %d : %v\n", len( *многоугольник ), многоугольник )
      fmt.Printf( "периметр = %.2f\n", многоугольник.perimeter() )
      fmt.Printf( "площадь = %.2f\n", многоугольник.square() )
      fmt.Println( "---------------------------------" )
   }
}
Я сразу же обращу внимание на такие пикантные операторы (я их повторно выпишу):

Код: Выделить всё

      r1, θ1 := cmplx.Polar( slice[ i + 1 ].xy - slice[ 0 ].xy ) 
      r2, θ2 := cmplx.Polar( slice[ i + 2 ].xy - slice[ 0 ].xy ) 
      summa += r1 * r2 * math.Abs( math.Sin( θ2 - θ1 ) ) / 2.
...
      многоугольник := new( shape )
...
      точка := new( point ) 
...
      ok, err := точка.inpoint()                        // ввод координат вершины
...
      многоугольник.append( *точка )
...
:-o

Сборка:

Код: Выделить всё

olej@notebook:~/2014_WORK/OWN.BOOKS/ManyLan/ex.draft/new-lang$ gccgo  triangle.go -o triangle
Выполнение:

Код: Выделить всё

olej@notebook:~/2014_WORK/OWN.BOOKS/ManyLan/ex.draft/news$ ./triangle
координаты вершин в формате: X Y
вершина № 1: 1 1
вершина № 2: 1 2
вершина № 3: 2 1
вершин 3 : [1,1] [1,2] [2,1]
периметр = 3.41
площадь = 0.50
---------------------------------
координаты вершин в формате: X Y
вершина № 1: 1 1
вершина № 2: 1 2
вершина № 3: 2 2
вершина № 4: 2 1
вершин 4 : [1,1] [1,2] [2,2] [2,1]
периметр = 4.00
площадь = 1.00
---------------------------------
координаты вершин в формате: X Y
вершина № 1: ^C
Вложения
triangle.go
(3.56 КБ) 492 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: сравнение языков программирования

Непрочитанное сообщение Olej » 15 фев 2014, 01:21

Olej писал(а): Я сразу же обращу внимание на такие пикантные операторы (я их повторно выпишу):

Код: Выделить всё

      r1, θ1 := cmplx.Polar( slice[ i + 1 ].xy - slice[ 0 ].xy ) 
      r2, θ2 := cmplx.Polar( slice[ i + 2 ].xy - slice[ 0 ].xy ) 
      summa += r1 * r2 * math.Abs( math.Sin( θ2 - θ1 ) ) / 2.
...
      многоугольник := new( shape )
...
      точка := new( point ) 
...
      ok, err := точка.inpoint()                        // ввод координат вершины
...
      многоугольник.append( *точка )
...
И ничего удивительного — просто последовательная поддержка UNICODE в кодировке UTF-8 в языке. Ведь Роб Пайк, один из идеологов Go, и был разработчиком системы кодирования UTF-8. В качестве идентификаторов допускаются символы алфавита любого языка, или математические символы.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: сравнение языков программирования

Непрочитанное сообщение Olej » 15 фев 2014, 12:32

Olej писал(а): И ничего удивительного — просто последовательная поддержка UNICODE в кодировке UTF-8 в языке. Ведь Роб Пайк, один из идеологов Go, и был разработчиком системы кодирования UTF-8. В качестве идентификаторов допускаются символы алфавита любого языка, или математические символы.
Но кроме этого, в языке есть масса вкусных "плюшек":

- язык очень изящный, сочетает ясность и лаконизм синтаксиса C (без необходимости лишних разделителей ';', завершающих каждый оператор), с отсутствием громоздкости, неподъёмности, тяжеловесности ... и вообще тягомутности C++ ("... и огород, на случай если Крот придёт..."(с) ... кто помнит такое ;-) );

- всё это дополнено механизмами классов и объектов, ... но механизмами лёгкими, без навязывания и фанатизма...

- устранена главная беда C - работа со строками: введено простое представление и лёгкие механизмы работы с текстовыми строками ... так как это делается в Python или скриптовых языках;

- есть указатели, но нет над ними адресной арифметики (как в Java) - это залог безопасности, работает динамическая сборка мусора и не нужно беспокоиться об уничтожении неиспользуемых динамических объектов

- есть масса приятных вещей, заимствованных из других языков (например из Python), таких как множественные возвраты из функций, ...

Этого бы уже достаточно для классного языка.
Но всё это ещё не есть главной "фишкой" Go...

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: сравнение языков программирования

Непрочитанное сообщение Olej » 15 фев 2014, 12:39

Olej писал(а):Этого бы уже достаточно для классного языка.
Но всё это не есть главной "фишкой" Go...
А главная "фишка" Go состоит в том, что язык предвосхитил (к началу разработки в 2007г. это не было очевидным!) тотальный переход всего компьютерного железа на многоядерность (многопроцессорность) и возможности параллельной обработки на многих процессорах. В этом он в чём то наследует процедурному языку параллельного программирования Occam, разработанному в начале 1980-х годов для программирования транспьютеров.

Язык предназначен для поддержания параллельного выполнения (реального, а не квази) на нескольких процессорах (ядрах). Для этого любую функцию Go можно запустить выполняться в отдельном потоке (оператором go). Параллельно выполняющиеся ветви выполняются как сопрограммы, и могут обмениваться между собой синхронными сообщениями через двунаправленные каналы. Через каналы могут передаваться данные любых типов.

Но чем 10 раз это рассказывать, лучше 1 раз это показать ;-) :

Код: Выделить всё

package main

import (
   "fmt"
   "time"
   "os"
)

func child( num int, in, out chan string ) {
   str1 := fmt.Sprintf( "%v : ", num )
   for { 
      str2 := <- in                 // строка полученная из входного канала
      fmt.Println( str1 + str2 ) 
      if out != nil { out <- str2 } // ретранслируется в выходной канал
   }
}

func ввод( ch chan string ) {
   const per = 300000000
   buf := make( [] byte, 1024 )
   for { 
      fmt.Printf( "> " )
      n, _ := os.Stdin.Read( buf )
      str := string( buf[ : n - 1 ] )
      fmt.Println( str )
      ch <- str
      time.Sleep( per )
   }
}

func main(){
   канал := [...] chan string { make( chan string ), make( chan string ),
                                make( chan string ), make( chan string ) }
   for i := range канал {
      if i != len( канал ) - 1 {
         go child( i, канал[ i ], канал[ i + 1 ] )
      } else {
         go child( i, канал[ i ], nil )
      }
   }
   ввод( канал[ 0 ] )
}
И вот как это происходит:

Код: Выделить всё

olej@notebook:~/2014_WORK/OWN.BOOKS/ManyLan/ex.draft/new-lang$ ./multy
> ввод
ввод
0 : ввод
1 : ввод
2 : ввод
3 : ввод
> srting from terminal
srting from terminal
0 : srting from terminal
1 : srting from terminal
2 : srting from terminal
3 : srting from terminal
> 123 456 789.000
123 456 789.000
0 : 123 456 789.000
1 : 123 456 789.000
2 : 123 456 789.000
3 : 123 456 789.000
> ^C
Вложения
multy.go
(1.05 КБ) 489 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: сравнение языков программирования

Непрочитанное сообщение Olej » 21 фев 2014, 03:25

Olej писал(а): В частности, из чисто компилирующих языков, например, - Go.
Следующий вариант - это чисто функциональные языки.
Первый из них - Scheme.
Scheme — один из двух наиболее популярных в наши дни диалектов языка Лисп (другой популярный диалект — это Common Lisp).

Компилятор и исполняющая система Scheme, имеющиеся во всех дистрибутивах - guile.

От Scheme оказывается довольно трудно добиться вывода русского текста (UTF-8) в терминал.
Это можно сделать так:

Код: Выделить всё

#!/usr/bin/guile -s 
!# 
(define stdout (current-output-port)) 
(set-port-encoding! stdout "utf-8") 

;; пробрная программа на Scheme - guile : 
(begin (write "Привет из Scheme, ") (write ( car (cdr (command-line)))) (newline)) 
(display "... вот так выводится русская строка\n" ) 

Код: Выделить всё

bash-4.2$ ./hello.scm Вася
"Привет из Scheme, ""Вася"
... вот так выводится русская строка

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: сравнение языков программирования

Непрочитанное сообщение Olej » 21 фев 2014, 03:29

Olej писал(а): Следующий вариант - это чисто функциональные языки.
Первый из них - Scheme.
Вариант эталонной программы на Scheme:

Код: Выделить всё

#!/usr/bin/guile -s
!#
(define stdout (current-output-port))
(set-port-encoding! stdout "utf-8")

(define d2 (lambda (f) (/ (round (* f 100.0)) 100.0) ))

(define (point n)         ; ввод и создание точки вершины
   (define x 0) (define y 0) (define z 0+0i)
   (display "вершина № ") (display n) (display " : ")
   (set! x (read))
   (cond ((eof-object? x) x)
      (else 
         (set! y (read))
         (cond ((eof-object? y) y)
            (else (set! z (+ x (* y 0+1i))) z)
         )
      ) 
   )
)

(define (put_point p)     ; вывод точки 
   (display "[" ) (display (d2 (real-part p)))
   (display "," ) (display (d2 (imag-part p))) (display "] " )
)

(define show              ; вывод вершин многоугольника
   (lambda ( lst ) 
   (map (lambda (x) (put_point x)) lst)))

(define (leng x)
   (let loop ((z x) (n 0))
      (if (null? z) n
         (loop (cdr z) (+ 1 n)))))

(define poligon           ; функция ввода кооринат вершин
   (lambda ( n lst )
      (define p 0+0i)
      (set! p (point n))  ; ввод новой вершины 
      (cond ((eof-object? p) (display "\r"))
            (else (set! lst (poligon (+ n  1 ) (cons p lst)))))
      lst
   )      
)

(define perimeter        ; периметр по списку вершин
   (lambda ( lst )
      (define size (lambda (p1 p2) (magnitude (- p1 p2))))
      (define head (car lst))
      (let ploop( (z lst) (per 0.0))
         (if (null? (cdr z ))
            (+ (size (car z) head) per)
            (ploop (cdr z) (+ (size (car z) (car (cdr z ))) per))))
   )
)      
    
(define square           ; площадь по списку вершин
   (lambda (lst)
      (define shead (car lst))
      (define triag (lambda (p1 p2) 
         (set! s1 (- p1 shead))
         (set! s2 (- p2 shead))
         (* (* (abs (sin (- (angle s2) (angle s1)))) 0.5)
            (* (magnitude s1) (magnitude s2)))
      ))
      (define s1 0+0i )
      (define s2 0+0i )
      (let sloop( (z (cdr lst)) (squ 0.0))
         (if (null? (cdr z )) squ
            (sloop (cdr z) (+ (triag (car z) (car (cdr z ))) squ))))
   )
)

(define next              ; цикл по фигурам
   (lambda ()
      (define shape '() )
      (display "координаты вершин в формате: X Y\n" )
      (set! shape (poligon 1 '()) )
      (display "вершин ") (display (leng shape))
      (display " : ") (show shape) (newline)
      (display "периметр = ") (display (d2 (perimeter shape))) (newline) 
      (display "площадь = ") (display (d2 (square  shape))) (newline) 
      (display "---------------------------------\n")
      (next)              ; рекурсия обеспечивает бесконечный цикл
))

(next)                    ; запуск всей программы
Громоздкость этой программы обусловлена множеством отдельных операций вывода (display) для придания внешнего поведения функциональной программе подобного её императивным эквивалентам, а оператор format() языка Scheme, похоже, просто сходит с ума, когда в выводе появляются UTF-8 коды.

Результат выполнения программы:

Код: Выделить всё

bash-4.2$ ./triangle.scm
координаты вершин в формате: X Y
вершина № 1 : 1 1
вершина № 2 : 1 2
вершина № 3 : 2 1
вершин 3 : [2.0,1.0] [1.0,2.0] [1.0,1.0]
периметр = 3.41
площадь = 0.5
---------------------------------
координаты вершин в формате: X Y
вершина № 1 : 1 1
вершина № 2 : 1 2
вершина № 3 : 2 2
вершина № 4 : 2 1
вершин 4 : [2.0,1.0] [2.0,2.0] [1.0,2.0] [1.0,1.0]
периметр = 4.0
площадь = 1.0
---------------------------------
координаты вершин в формате: X Y
вершина № 1 : ^C
Похоже? ;-)
Вложения
triangle.scm
(2.82 КБ) 493 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: сравнение языков программирования

Непрочитанное сообщение Olej » 22 фев 2014, 18:48

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
Вложения
triangle.scala
(3.18 КБ) 488 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: сравнение языков программирования

Непрочитанное сообщение Olej » 27 фев 2014, 23:31

Olej писал(а): Следующий вариант: Scala.
Ещё один вариант Ocaml - Objective Caml, клон функционального языка ML.

Порог начального вхождения в программирование Ocaml — высокий, и к этому нужно быть готовым.
Главным образом из-за документации...
Документация по языку - чудовищно плохая (хоть её и много):
- Документация Ocaml писалась на французском языке и давно, с неё делались не очень умелые переводы на английский, а а уже с него — те рваные переводы и описания, которые доступны на русском.
- Ещё одна черта информационных источников по Ocaml, которая явно прослеживается, состоит в том, что написано это всё в академических, университетских кругах: много замысловатых конструкций и примеров, но нет систематического изложения и мало пригодно для практического использования.
- Время жизни языка (начиная с клона ML) достаточно велико, совместимостью между версиями авторы не озадачивались, а в документации не указываются ни версии, ни сроки написания — большинство примеров из документации и учебников просто не компилируется.

Вот как выглядит здесь наша задача:

Код: Выделить всё

open Complex;;

let print_point pt =                            (* вывод комплексного числа - координаты *)
   print_string "[";
   print_float pt.re;
   print_string ",";
   print_float pt.im;
   print_string "] ";; 

let rec poligon shape n =                       (* ввод координат многоугольника *)
   print_string "вершина №";
   print_int n;
   print_string " : ";
   Format.print_flush();
   try
      let str = read_line() in
      try
         let pt = Scanf.sscanf str "%f %f" (fun x y -> { re=x; im=y }) in  
         let lst = pt :: shape in
         poligon lst ( n + 1 );
      with float_of_string ->                   (* ошибка формата ввода*)
         print_string "ошибка ввода!\n";
         poligon shape n;
   with End_of_file ->                          (* ^D - конец списка вершин *) 
      shape;; 

let rec show shape =                            (* вывод координат многоугольника *)
   match shape with
   | [] -> 
     print_newline();
   | hd :: tl -> 
     print_point hd;
     show tl;;

let perimeter shape = 
   let dist p1 p2 = norm( sub p1 p2 ) in        (* расстояние между 2-мя точками*)
   let rec add_line lst sum = 
      if List.tl( lst ) = [] then 
         dist (List.hd lst) (List.hd shape)     (* последняя точка *)
      else 
         dist (List.hd lst) (List.hd( List.tl lst )) +.
         add_line (List.tl lst ) sum            (* промежуточные точки *)
   in                                           (* end add_line *)
   add_line shape 0.0;;                         (* накапливающая сумма *)

let square shape =
   let triang p1 p2 =
      let s1 = sub p1 ( List.hd shape ) in
      let s2 = sub p2 ( List.hd shape ) in
         norm( s1 ) *. norm( s2 ) *. abs_float( sin( ( arg( s1 ) -. arg( s2 ) ) ) ) /. 2.0
   in                                           (* end triang *)
   let rec add_squa lst sum =
      let squa = triang (List.hd lst) (List.hd( List.tl lst )) in
      if List.tl( List.tl lst ) = [] then squa
      else 
         squa +. add_squa (List.tl lst ) sum   
   in                                           (* end add_squa *)
   add_squa (List.tl shape) 0.0;; 

let rec next() =
   print_string "координаты вершин в формате: X Y (^D конец ввода)\n";
   let shape = poligon [] 1 in
   begin
      print_string "\rвершин ";
      print_int( List.length shape );
      print_string " : ";
      show shape ;
      print_string "периметр = ";
      print_float( perimeter shape ); 
      print_newline();
      print_string "площадь = ";
      print_float( square shape );
      print_newline();
      print_string "---------------------------------\n";
      next();                                   (* рекурсивно организованный бесконечный цикл *)
   end;;

next();;
Выполнение...
Выполнять Ocaml можно разными способами (это если не считать ещё интерактивного калькулятора):

- непосредственной интерпретацией кода:

Код: Выделить всё

$ ocam triangle_ml.ml
координаты вершин в формате: X Y (^D конец ввода)
...
- компиляцией в байт-код с последующим его выполнением:

Код: Выделить всё

$ ocamlc triangle_ml.ml -o triangle_ml 
$ ocamlrun triangle_ml
координаты вершин в формате: X Y (^D конец ввода)
...
- оптимизирующей компиляцией в бинарный исполнимый формат (ELF в случае Linux) и его выполнение:

Код: Выделить всё

$ ocamlopt triangle_ml.ml -o triangle_ml 
$ ./triangle_ml
координаты вершин в формате: X Y (^D конец ввода)
вершина №1 : 1 1
вершина №2 : 1 2
вершина №3 : 2 1
вершин 3 : [2.,1.] [1.,2.] [1.,1.]
периметр = 3.41421356237
площадь = 0.5
---------------------------------
координаты вершин в формате: X Y (^D конец ввода)
вершина №1 : 1 1
вершина №2 : 1 2
вершина №3 : 2 2
вершина №4 : 2 1
вершин 4 : [2.,1.] [2.,2.] [1.,2.] [1.,1.]
периметр = 4.
площадь = 1.
---------------------------------
координаты вершин в формате: X Y (^D конец ввода)
вершин 0 : ^C
В этом примере кода есть и обработка ошибок ввода (исключения):

Код: Выделить всё

$ ocaml triangle_ml.ml
координаты вершин в формате: X Y (^D конец ввода)
вершина №1 : 1 2
вершина №2 : 2 r
ошибка ввода!
вершина №2 : 5,5 6
ошибка ввода!
вершина №2 : 3 4
...
Вложения
triangle_ml.ml
(2.97 КБ) 511 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: сравнение языков программирования

Непрочитанное сообщение Olej » 28 фев 2014, 00:27

Итого ... в порядке промежуточного итога ... я показал здесь сравнительную реализацию одной и той же задачи на:

1. 10 самых востребованных в практивке языков программирования:
Olej писал(а): - C
- C++
- Java
- Python
- JavaScript
- PHP
- Lua
- bash
- Perl
- Ruby
2. ещё то же самое на 4-х более экзртических языках программирования:
- Go
- Scheme
- Scala
- Ocaml

P.S. Возможно (если будет время, здоровье и желание ;-) ) проделаю то же самое ещё не каких-то языках из числа: Haskell, haXe, Zimbu, X10, Chapel, ...

Здесь бывали (обсуждали) на форуме кто-то из преподавателей ВУЗ-овских... Вот можете взять этот материал за основу, и сделать начальный курс обучения программистов - внешний такой взгляд (по верхам) на языки программирования.

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 8 гостей