julia.md

Личный сайт Go-разработчика из Казани

Julia — гомоиконный функциональный язык программирования для технических расчётов. Несмотря на полную поддержку гомоиконных макросов, функций первого класса и конструкций управления низкого уровня, этот язык так же прост в изучении и применении, как и Python.

Документ описывает текущую dev-версию Julia от 18-о октября 2013 года.

1# Однострочные комментарии начинаются со знака решётки. 2 3#################################################### 4## 1. Примитивные типы данных и операторы 5#################################################### 6 7# Всё в Julia — выражение. 8 9# Простые численные типы 103 # => 3 (Int64) 113.2 # => 3.2 (Float64) 122 + 1im # => 2 + 1im (Complex{Int64}) 132//3 # => 2//3 (Rational{Int64}) 14 15# Доступны все привычные инфиксные операторы 161 + 1 # => 2 178 - 1 # => 7 1810 * 2 # => 20 1935 / 5 # => 7.0 205 / 2 # => 2.5 # деление Int на Int всегда возвращает Float 21div(5, 2) # => 2 # для округления к нулю используется div 225 \ 35 # => 7.0 232 ^ 2 # => 4 # возведение в степень 2412 % 10 # => 2 25 26# С помощью скобок можно изменить приоритет операций 27(1 + 3) * 2 # => 8 28 29# Побитовые операторы 30~2 # => -3 # НЕ (NOT) 313 & 5 # => 1 # И (AND) 322 | 4 # => 6 # ИЛИ (OR) 332 $ 4 # => 6 # сложение по модулю 2 (XOR) 342 >>> 1 # => 1 # логический сдвиг вправо 352 >> 1 # => 1 # арифметический сдвиг вправо 362 << 1 # => 4 # логический/арифметический сдвиг влево 37 38# Функция bits возвращает бинарное представление числа 39bits(12345) 40# => "0000000000000000000000000000000000000000000000000011000000111001" 41bits(12345.0) 42# => "0100000011001000000111001000000000000000000000000000000000000000" 43 44# Логические значения являются примитивами 45true 46false 47 48# Булевы операторы 49!true # => false 50!false # => true 511 == 1 # => true 522 == 1 # => false 531 != 1 # => false 542 != 1 # => true 551 < 10 # => true 561 > 10 # => false 572 <= 2 # => true 582 >= 2 # => true 59# Сравнения можно объединять цепочкой 601 < 2 < 3 # => true 612 < 3 < 2 # => false 62 63# Строки объявляются с помощью двойных кавычек — " 64"This is a string." 65 66# Символьные литералы создаются с помощью одинарных кавычек — ' 67'a' 68 69# Строки индексируются как массивы символов 70"This is a string"[1] # => 'T' # Индексы начинаются с единицы 71# Индексирование не всегда правильно работает для UTF8-строк, 72# поэтому рекомендуется использовать итерирование (map, for-циклы и т.п.). 73 74# Для строковой интерполяции используется знак доллара ($): 75"2 + 2 = $(2 + 2)" # => "2 + 2 = 4" 76# В скобках можно использовать любое выражение языка. 77 78# Другой способ форматирования строк — макрос printf 79@printf "%d is less than %f" 4.5 5.3 # 5 is less than 5.300000 80 81#################################################### 82## 2. Переменные и коллекции 83#################################################### 84 85# Вывод 86println("I'm Julia. Nice to meet you!") 87 88# Переменные инициализируются без предварительного объявления 89some_var = 5 # => 5 90some_var # => 5 91 92# Попытка доступа к переменной до инициализации вызывает ошибку 93try 94 some_other_var # => ERROR: some_other_var not defined 95catch e 96 println(e) 97end 98 99# Имена переменных начинаются с букв. 100# После первого символа можно использовать буквы, цифры, 101# символы подчёркивания и восклицательные знаки. 102SomeOtherVar123! = 6 # => 6 103 104# Допустимо использование unicode-символов 105= 8 # => 8 106# Это особенно удобно для математических обозначений 1072 * π # => 6.283185307179586 108 109# Рекомендации по именованию: 110# * имена переменных в нижнем регистре, слова разделяются символом 111# подчёркивания ('\_'); 112# 113# * для имён типов используется CamelCase; 114# 115# * имена функций и макросов в нижнем регистре 116# без разделения слов символом подчёркивания; 117# 118# * имя функции, изменяющей переданные ей аргументы (in-place function), 119# оканчивается восклицательным знаком. 120 121# Массив хранит последовательность значений, индексируемых с единицы до n: 122a = Int64[] # => пустой массив Int64-элементов 123 124# Одномерный массив объявляется разделёнными запятой значениями. 125b = [4, 5, 6] # => массив из трёх Int64-элементов: [4, 5, 6] 126b[1] # => 4 127b[end] # => 6 128 129# Строки двумерного массива разделяются точкой с запятой. 130# Элементы строк разделяются пробелами. 131matrix = [1 2; 3 4] # => 2x2 Int64 Array: [1 2; 3 4] 132 133# push! и append! добавляют в список новые элементы 134push!(a,1) # => [1] 135push!(a,2) # => [1,2] 136push!(a,4) # => [1,2,4] 137push!(a,3) # => [1,2,4,3] 138append!(a,b) # => [1,2,4,3,4,5,6] 139 140# pop! удаляет из списка последний элемент 141pop!(b) # => возвращает 6; массив b снова равен [4,5] 142 143# Вернём 6 обратно 144push!(b,6) # b снова [4,5,6]. 145 146a[1] # => 1 # индексы начинаются с единицы! 147 148# Последний элемент можно получить с помощью end 149a[end] # => 6 150 151# Операции сдвига 152shift!(a) # => 1 and a is now [2,4,3,4,5,6] 153unshift!(a,7) # => [7,2,4,3,4,5,6] 154 155# Восклицательный знак на конце названия функции означает, 156# что функция изменяет переданные ей аргументы. 157arr = [5,4,6] # => массив из 3 Int64-элементов: [5,4,6] 158sort(arr) # => [4,5,6]; но arr равен [5,4,6] 159sort!(arr) # => [4,5,6]; а теперь arr — [4,5,6] 160 161# Попытка доступа за пределами массива выбрасывает BoundsError 162try 163 a[0] # => ERROR: BoundsError() in getindex at array.jl:270 164 a[end+1] # => ERROR: BoundsError() in getindex at array.jl:270 165catch e 166 println(e) 167end 168 169# Вывод ошибок содержит строку и файл, где произошла ошибка, 170# даже если это случилось в стандартной библиотеке. 171# Если вы собрали Julia из исходных кодов, 172# то найти эти файлы можно в директории base. 173 174# Создавать массивы можно из последовательности 175a = [1:5] # => массив из 5 Int64-элементов: [1,2,3,4,5] 176 177# Срезы 178a[1:3] # => [1, 2, 3] 179a[2:] # => [2, 3, 4, 5] 180a[2:end] # => [2, 3, 4, 5] 181 182# splice! удаляет элемент из массива 183# Remove elements from an array by index with splice! 184arr = [3,4,5] 185splice!(arr,2) # => 4 ; arr теперь равен [3,5] 186 187# append! объединяет списки 188b = [1,2,3] 189append!(a,b) # теперь a равен [1, 2, 3, 4, 5, 1, 2, 3] 190 191# Проверка на вхождение 192in(1, a) # => true 193 194# Длина списка 195length(a) # => 8 196 197# Кортеж — неизменяемая структура. 198tup = (1, 2, 3) # => (1,2,3) # кортеж (Int64,Int64,Int64). 199tup[1] # => 1 200try: 201 tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64) 202catch e 203 println(e) 204end 205 206# Многие функции над списками работают и для кортежей 207length(tup) # => 3 208tup[1:2] # => (1,2) 209in(2, tup) # => true 210 211# Кортежи можно распаковывать в переменные 212a, b, c = (1, 2, 3) # => (1,2,3) # a = 1, b = 2 и c = 3 213 214# Скобки из предыдущего примера можно опустить 215d, e, f = 4, 5, 6 # => (4,5,6) 216 217# Кортеж из одного элемента не равен значению этого элемента 218(1,) == 1 # => false 219(1) == 1 # => true 220 221# Обмен значений 222e, d = d, e # => (5,4) # d = 5, e = 4 223 224 225# Словари содержат ассоциативные массивы 226empty_dict = Dict() # => Dict{Any,Any}() 227 228# Для создания словаря можно использовать литерал 229filled_dict = ["one"=> 1, "two"=> 2, "three"=> 3] 230# => Dict{ASCIIString,Int64} 231 232# Значения ищутся по ключу с помощью оператора [] 233filled_dict["one"] # => 1 234 235# Получить все ключи 236keys(filled_dict) 237# => KeyIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2]) 238# Заметьте, словарь не запоминает порядок, в котором добавляются ключи. 239 240# Получить все значения. 241values(filled_dict) 242# => ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2]) 243# То же касается и порядка значений. 244 245# Проверка вхождения ключа в словарь 246in(("one", 1), filled_dict) # => true 247in(("two", 3), filled_dict) # => false 248haskey(filled_dict, "one") # => true 249haskey(filled_dict, 1) # => false 250 251# Попытка обратиться к несуществующему ключу выбросит ошибку 252try 253 filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489 254catch e 255 println(e) 256end 257 258# Используйте метод get со значением по умолчанию, чтобы избежать этой ошибки 259# get(dictionary,key,default_value) 260get(filled_dict,"one",4) # => 1 261get(filled_dict,"four",4) # => 4 262 263# Для коллекций неотсортированных уникальных элементов используйте Set 264empty_set = Set() # => Set{Any}() 265# Инициализация множества 266filled_set = Set(1,2,2,3,4) # => Set{Int64}(1,2,3,4) 267 268# Добавление элементов 269push!(filled_set,5) # => Set{Int64}(5,4,2,3,1) 270 271# Проверка вхождения элементов во множество 272in(2, filled_set) # => true 273in(10, filled_set) # => false 274 275# Функции для получения пересечения, объединения и разницы. 276other_set = Set(3, 4, 5, 6) # => Set{Int64}(6,4,5,3) 277intersect(filled_set, other_set) # => Set{Int64}(3,4,5) 278union(filled_set, other_set) # => Set{Int64}(1,2,3,4,5,6) 279setdiff(Set(1,2,3,4),Set(2,3,5)) # => Set{Int64}(1,4) 280 281 282#################################################### 283## 3. Поток управления 284#################################################### 285 286# Создадим переменную 287some_var = 5 288 289# Выражение if. Отступы не имеют значения. 290if some_var > 10 291 println("some_var is totally bigger than 10.") 292elseif some_var < 10 # Необязательная ветка elseif. 293 println("some_var is smaller than 10.") 294else # else-ветка также опциональна. 295 println("some_var is indeed 10.") 296end 297# => prints "some var is smaller than 10" 298 299 300# Цикл for проходит по итерируемым объектам 301# Примеры итерируемых типов: Range, Array, Set, Dict и String. 302for animal=["dog", "cat", "mouse"] 303 println("$animal is a mammal") 304 # Для вставки значения переменной или выражения в строку используется $ 305end 306# Выведет: 307# dog is a mammal 308# cat is a mammal 309# mouse is a mammal 310 311# Другой вариант записи. 312for animal in ["dog", "cat", "mouse"] 313 println("$animal is a mammal") 314end 315# Выведет: 316# dog is a mammal 317# cat is a mammal 318# mouse is a mammal 319 320for a in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"] 321 println("$(a[1]) is a $(a[2])") 322end 323# Выведет: 324# dog is a mammal 325# cat is a mammal 326# mouse is a mammal 327 328for (k,v) in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"] 329 println("$k is a $v") 330end 331# Выведет: 332# dog is a mammal 333# cat is a mammal 334# mouse is a mammal 335 336# Цикл while выполняется до тех пор, пока верно условие 337x = 0 338while x < 4 339 println(x) 340 x += 1 # Короткая запись x = x + 1 341end 342# Выведет: 343# 0 344# 1 345# 2 346# 3 347 348# Обработка исключений 349try 350 error("help") 351catch e 352 println("caught it $e") 353end 354# => caught it ErrorException("help") 355 356 357#################################################### 358## 4. Функции 359#################################################### 360 361# Для определения новой функции используется ключевое слово 'function' 362#function имя(аргументы) 363# тело... 364#end 365function add(x, y) 366 println("x is $x and y is $y") 367 368 # Функция возвращает значение последнего выражения 369 x + y 370end 371 372add(5, 6) # => Вернёт 11, напечатав "x is 5 and y is 6" 373 374# Функция может принимать переменное количество позиционных аргументов. 375function varargs(args...) 376 return args 377 # для возвращения из функции в любом месте используется 'return' 378end 379# => varargs (generic function with 1 method) 380 381varargs(1,2,3) # => (1,2,3) 382 383# Многоточие (...) — это splat. 384# Мы только что воспользовались им в определении функции. 385# Также его можно использовать при вызове функции, 386# где он преобразует содержимое массива или кортежа в список аргументов. 387Set([1,2,3]) # => Set{Array{Int64,1}}([1,2,3]) # формирует множество массивов 388Set([1,2,3]...) # => Set{Int64}(1,2,3) # эквивалентно Set(1,2,3) 389 390x = (1,2,3) # => (1,2,3) 391Set(x) # => Set{(Int64,Int64,Int64)}((1,2,3)) # множество кортежей 392Set(x...) # => Set{Int64}(2,3,1) 393 394 395# Опциональные позиционные аргументы 396function defaults(a,b,x=5,y=6) 397 return "$a $b and $x $y" 398end 399 400defaults('h','g') # => "h g and 5 6" 401defaults('h','g','j') # => "h g and j 6" 402defaults('h','g','j','k') # => "h g and j k" 403try 404 defaults('h') # => ERROR: no method defaults(Char,) 405 defaults() # => ERROR: no methods defaults() 406catch e 407 println(e) 408end 409 410# Именованные аргументы 411function keyword_args(;k1=4,name2="hello") # обратите внимание на ; 412 return ["k1"=>k1,"name2"=>name2] 413end 414 415keyword_args(name2="ness") # => ["name2"=>"ness","k1"=>4] 416keyword_args(k1="mine") # => ["k1"=>"mine","name2"=>"hello"] 417keyword_args() # => ["name2"=>"hello","k2"=>4] 418 419# В одной функции можно совмещать все виды аргументов 420function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo") 421 println("normal arg: $normal_arg") 422 println("optional arg: $optional_positional_arg") 423 println("keyword arg: $keyword_arg") 424end 425 426all_the_args(1, 3, keyword_arg=4) 427# Выведет: 428# normal arg: 1 429# optional arg: 3 430# keyword arg: 4 431 432# Функции в Julia первого класса 433function create_adder(x) 434 adder = function (y) 435 return x + y 436 end 437 return adder 438end 439 440# Анонимная функция 441(x -> x > 2)(3) # => true 442 443# Эта функция идентичная предыдущей версии create_adder 444function create_adder(x) 445 y -> x + y 446end 447 448# Если есть желание, можно воспользоваться полным вариантом 449function create_adder(x) 450 function adder(y) 451 x + y 452 end 453 adder 454end 455 456add_10 = create_adder(10) 457add_10(3) # => 13 458 459 460# Встроенные функции высшего порядка 461map(add_10, [1,2,3]) # => [11, 12, 13] 462filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7] 463 464# Списковые сборки 465[add_10(i) for i=[1, 2, 3]] # => [11, 12, 13] 466[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] 467 468#################################################### 469## 5. Типы 470#################################################### 471 472# Julia has a type system. 473# Каждое значение имеет тип, но переменные не определяют тип значения. 474# Функция `typeof` возвращает тип значения. 475typeof(5) # => Int64 476 477# Types are first-class values 478# Типы являются значениями первого класса 479typeof(Int64) # => DataType 480typeof(DataType) # => DataType 481# Тип DataType представляет типы, включая себя самого. 482 483# Типы используются в качестве документации, для оптимизации и организации. 484# Статически типы не проверяются. 485 486# Пользователь может определять свои типы 487# Типы похожи на структуры в других языках 488# Новые типы определяются с помощью ключевого слова `type` 489 490# type Name 491# field::OptionalType 492# ... 493# end 494type Tiger 495 taillength::Float64 496 coatcolor # отсутствие типа равносильно `::Any` 497end 498 499# Аргументы конструктора по умолчанию — свойства типа 500# в порядке их определения. 501tigger = Tiger(3.5,"orange") # => Tiger(3.5,"orange") 502 503# Тип объекта по сути является конструктором значений такого типа 504sherekhan = typeof(tigger)(5.6,"fire") # => Tiger(5.6,"fire") 505 506# Эти типы, похожие на структуры, называются конкретными. 507# Можно создавать объекты таких типов, но не их подтипы. 508# Другой вид типов — абстрактные типы. 509 510# abstract Name 511abstract Cat # просто имя и точка в иерархии типов 512 513# Объекты абстрактных типов создавать нельзя, 514# но зато от них можно наследовать подтипы. 515# Например, Number — это абстрактный тип. 516subtypes(Number) # => 6 элементов в массиве Array{Any,1}: 517 # Complex{Float16} 518 # Complex{Float32} 519 # Complex{Float64} 520 # Complex{T<:Real} 521 # ImaginaryUnit 522 # Real 523subtypes(Cat) # => пустой массив Array{Any,1} 524 525# У всех типов есть супертип. Для его определения есть функция `super`. 526typeof(5) # => Int64 527super(Int64) # => Signed 528super(Signed) # => Real 529super(Real) # => Number 530super(Number) # => Any 531super(super(Signed)) # => Number 532super(Any) # => Any 533# Все эти типы, за исключением Int64, абстрактные. 534 535# Для создания подтипа используется оператор <: 536type Lion <: Cat # Lion — это подтип Cat 537 mane_color 538 roar::String 539end 540 541# У типа может быть несколько конструкторов. 542# Для создания нового определите функцию с именем, как у типа, 543# и вызовите имеющийся конструктор. 544Lion(roar::String) = Lion("green",roar) 545# Мы создали внешний (т.к. он находится вне определения типа) конструктор. 546 547type Panther <: Cat # Panther — это тоже подтип Cat 548 eye_color 549 550 # Определим свой конструктор вместо конструктора по умолчанию 551 Panther() = new("green") 552end 553# Использование внутренних конструкторов позволяет 554# определять, как будут создаваться объекты типов. 555# Но по возможности стоит пользоваться внешними конструкторами. 556 557#################################################### 558## 6. Мультиметоды 559#################################################### 560 561# Все именованные функции являются generic-функциями, 562# т.е. все они состоят из разных методов. 563# Каждый конструктор типа Lion — это метод generic-функции Lion. 564 565# Приведём пример без использования конструкторов, создадим функцию meow 566 567# Определения Lion, Panther и Tiger 568function meow(animal::Lion) 569 animal.roar # доступ к свойству типа через точку 570end 571 572function meow(animal::Panther) 573 "grrr" 574end 575 576function meow(animal::Tiger) 577 "rawwwr" 578end 579 580# Проверка 581meow(tigger) # => "rawwr" 582meow(Lion("brown","ROAAR")) # => "ROAAR" 583meow(Panther()) # => "grrr" 584 585# Вспомним иерархию типов 586issubtype(Tiger,Cat) # => false 587issubtype(Lion,Cat) # => true 588issubtype(Panther,Cat) # => true 589 590# Определим функцию, принимающую на вход объекты типа Cat 591function pet_cat(cat::Cat) 592 println("The cat says $(meow(cat))") 593end 594 595pet_cat(Lion("42")) # => выведет "The cat says 42" 596try 597 pet_cat(tigger) # => ERROR: no method pet_cat(Tiger,) 598catch e 599 println(e) 600end 601 602# В объектно-ориентированных языках распространена одиночная диспетчеризация — 603# подходящий метод выбирается на основе типа первого аргумента. 604# В Julia все аргументы участвуют в выборе нужного метода. 605 606# Чтобы понять разницу, определим функцию с несколькими аргументами. 607function fight(t::Tiger,c::Cat) 608 println("The $(t.coatcolor) tiger wins!") 609end 610# => fight (generic function with 1 method) 611 612fight(tigger,Panther()) # => выведет The orange tiger wins! 613fight(tigger,Lion("ROAR")) # => выведет The orange tiger wins! 614 615# Переопределим поведение функции, если Cat-объект является Lion-объектом 616fight(t::Tiger,l::Lion) = println("The $(l.mane_color)-maned lion wins!") 617# => fight (generic function with 2 methods) 618 619fight(tigger,Panther()) # => выведет The orange tiger wins! 620fight(tigger,Lion("ROAR")) # => выведет The green-maned lion wins! 621 622# Драться можно не только с тиграми! 623fight(l::Lion,c::Cat) = println("The victorious cat says $(meow(c))") 624# => fight (generic function with 3 methods) 625 626fight(Lion("balooga!"),Panther()) # => выведет The victorious cat says grrr 627try 628 fight(Panther(),Lion("RAWR")) # => ERROR: no method fight(Panther,Lion) 629catch 630end 631 632# Вообще, пускай кошачьи могут первыми проявлять агрессию 633fight(c::Cat,l::Lion) = println("The cat beats the Lion") 634# => Warning: New definition 635# fight(Cat,Lion) at none:1 636# is ambiguous with 637# fight(Lion,Cat) at none:2. 638# Make sure 639# fight(Lion,Lion) 640# is defined first. 641#fight (generic function with 4 methods) 642 643# Предупреждение говорит, что неясно, какой из методов вызывать: 644fight(Lion("RAR"),Lion("brown","rarrr")) # => выведет The victorious cat says rarrr 645# Результат может оказаться разным в разных версиях Julia 646 647fight(l::Lion,l2::Lion) = println("The lions come to a tie") 648fight(Lion("RAR"),Lion("brown","rarrr")) # => выведет The lions come to a tie 649 650 651# Под капотом 652# Язык позволяет посмотреть на сгенерированные ассемблерный и LLVM-код. 653 654square_area(l) = l * l # square_area (generic function with 1 method) 655 656square_area(5) #25 657 658# Что происходит, когда мы передаём функции square_area целое число? 659code_native(square_area, (Int32,)) 660 # .section __TEXT,__text,regular,pure_instructions 661 # Filename: none 662 # Source line: 1 # Вводная часть 663 # push RBP 664 # mov RBP, RSP 665 # Source line: 1 666 # movsxd RAX, EDI # 667 # imul RAX, RAX # 668 # pop RBP # 669 # ret # 670 671code_native(square_area, (Float32,)) 672 # .section __TEXT,__text,regular,pure_instructions 673 # Filename: none 674 # Source line: 1 675 # push RBP 676 # mov RBP, RSP 677 # Source line: 1 678 # vmulss XMM0, XMM0, XMM0 # Произведение чисел одинарной точности (AVX) 679 # pop RBP 680 # ret 681 682code_native(square_area, (Float64,)) 683 # .section __TEXT,__text,regular,pure_instructions 684 # Filename: none 685 # Source line: 1 686 # push RBP 687 # mov RBP, RSP 688 # Source line: 1 689 # vmulsd XMM0, XMM0, XMM0 # Произведение чисел двойной точности (AVX) 690 # pop RBP 691 # ret 692 # 693# Если хотя бы один из аргументов является числом с плавающей запятой, 694# то Julia будет использовать соответствующие инструкции. 695# Вычислим площать круга 696circle_area(r) = pi * r * r # circle_area (generic function with 1 method) 697circle_area(5) # 78.53981633974483 698 699code_native(circle_area, (Int32,)) 700 # .section __TEXT,__text,regular,pure_instructions 701 # Filename: none 702 # Source line: 1 703 # push RBP 704 # mov RBP, RSP 705 # Source line: 1 706 # vcvtsi2sd XMM0, XMM0, EDI # Загрузить целое число (r) 707 # movabs RAX, 4593140240 # Загрузить pi 708 # vmulsd XMM1, XMM0, QWORD PTR [RAX] # pi * r 709 # vmulsd XMM0, XMM0, XMM1 # (pi * r) * r 710 # pop RBP 711 # ret 712 # 713 714code_native(circle_area, (Float64,)) 715 # .section __TEXT,__text,regular,pure_instructions 716 # Filename: none 717 # Source line: 1 718 # push RBP 719 # mov RBP, RSP 720 # movabs RAX, 4593140496 721 # Source line: 1 722 # vmulsd XMM1, XMM0, QWORD PTR [RAX] 723 # vmulsd XMM0, XMM1, XMM0 724 # pop RBP 725 # ret 726 #

Что дальше?

Для более подробной информации читайте документацию по языку

Если вам нужна помощь, задавайте вопросы в списке рассылки.