Crystal - это компилируемый, объектно-ориентированный язык программирования общего назначения со статической типизацией, спроектированный и разработанный Ary Borenszweig, Juan Wajnerman, Brian Cardiff и другими.
Благодаря этому код легко пишется и читается, а порог вхождения очень низкий для Ruby разработчиков с опытом.
Так же Crystal имеет встроенный вывод типов, что позволяет не указывать большинство типов, делая язык более читабельным.
В итоге компилятор выполнит автоматическую проверки на нулевые указатели, избавляя от ужасных последствий.
Запустив этот код, компилятор выдаст ошибку
Fiber-ы общаются друг с другом с помощью каналов, как в Go или Clojure, не прибегая к разделяемой памяти или блокировкам.
Встроенные команды позволяют указывать зависимости в YAML файле и получать их из указанных источников.
Если тебе понравилась данная статья, хочешь больше статей по Crystal и есть желание изучить его, ставь лайк
Синтаксис
На синтаксис Crystal сильное влияние оказал язык программирования Ruby.Благодаря этому код легко пишется и читается, а порог вхождения очень низкий для Ruby разработчиков с опытом.
Ruby:
# A very basic HTTP server
require "http/server"
server = HTTP::Server.new do |context|
context.response.content_type = "text/plain"
context.response.print "Hello world, got #{context.request.path}!"
end
puts "Listening on http://127.0.0.1:8080"
server.listen(8080)
Система типов
В Crystal используется статическая проверка типа и соответственно любые ошибки типов будут отловлены компилятором, не допуская падения в рантайме.Так же Crystal имеет встроенный вывод типов, что позволяет не указывать большинство типов, делая язык более читабельным.
Ruby:
def shout(x)
# Notice that both Int32 and String respond_to `to_s`
x.to_s.upcase
end
foo = ENV["FOO"]? || 10
typeof(foo) # => (Int32 | String)
typeof(shout(foo)) # => String
Проверка нулевых указателей
Все типы в Crystal являются ненулевыми, а все нулевые переменные представлены как объединение между типом и nil.В итоге компилятор выполнит автоматическую проверки на нулевые указатели, избавляя от ужасных последствий.
Ruby:
if rand(2) > 0
my_string = "hello world"
end
puts my_string.upcase
Код:
$ crystal hello_world.cr
Error in hello_world.cr:5: undefined method 'upcase' for Nil (compile-time type is (String | Nil))
puts my_string.upcase
^~~~~~
Макросы
Для метапрограммирования Crystal предлагает мощную систему макросов, от базового шаблонизатор и испектирования AST, до испектирования типов и запуска любых внешних программ.
Ruby:
class Object
def has_instance_var?(name) : Bool
{{ @type.instance_vars.map &.name.stringify }}.includes? name
end
end
person = Person.new "John", 30
person.has_instance_var?("name") #=> true
person.has_instance_var?("birthday") #=> false
Многопоточная модель
Crystal использует зелёные потоки (green threads), называемые волокнами (fibers), для получения многопоточности.Fiber-ы общаются друг с другом с помощью каналов, как в Go или Clojure, не прибегая к разделяемой памяти или блокировкам.
Ruby:
channel = Channel(Int32).new
total_lines = 0
files = Dir.glob("*.txt")
files.each do |f|
spawn do
lines = File.read_lines(f)
channel.send lines.size
end
end
files.size.times do
total_lines += channel.receive
end
puts total_lines
Привязки к C библиотекам
Crystal предлагает специальный синтаксис для работы с нативными библиотеками, избавляя от необходимости переизобретать низкоуровневые примитивы.
Ruby:
# Fragment of the BigInt implementation that uses GMP
@[Link("gmp")]
lib LibGMP
alias Int = LibC::Int
alias ULong = LibC::ULong
struct MPZ
_mp_alloc : Int32
_mp_size : Int32
_mp_d : ULong*
end
fun init_set_str = __gmpz_init_set_str(rop : MPZ*, str : UInt8*, base : Int) : Int
fun cmp = __gmpz_cmp(op1 : MPZ*, op2 : MPZ*) : Int
end
struct BigInt < Int
def initialize(str : String, base = 10)
err = LibGMP.init_set_str(out @mpz, str, base)
raise ArgumentError.new("invalid BigInt: #{str}") if err == -1
end
def <=>(other : BigInt)
LibGMP.cmp(mpz, other)
end
end
Зависимости
Библиотека Crystal упаковываются в осколки (shards) и распространяются с помощью Git, не нуждаясь в централизованном репозитории.Встроенные команды позволяют указывать зависимости в YAML файле и получать их из указанных источников.
YAML:
name: my-project
version: 0.1
license: MIT
crystal: 0.21.0
dependencies:
mysql:
github: crystal-lang/crystal-mysql
version: ~> 0.3.1
Если тебе понравилась данная статья, хочешь больше статей по Crystal и есть желание изучить его, ставь лайк