Изучение нового языка заключается в изучении словарного запаса и синтаксиса. Это верно независимо от того, изучаете ли вы иностранный (разговорный) язык или язык программирования. Но даже когда вы изучаете правила функционирования языка, всегда есть оговорки — вещи, которые не совсем соответствуют правилам. В английском языке, безусловно, их много, как и в языках программирования. Вы улавливаете исключения из правил в разговорной речи, слушая, как говорят другие люди.

Вы улавливаете особенности языка программирования, пробуя разные вещи и наблюдая, что вы получаете в результате. Многие языки программирования имеют удобную функцию, называемую REPL, сокращенно от Read Evaluate Print Loop, специально разработанную для такого типа экспериментов.

Понимание того, что является допустимым вводом для языка, может иметь значение между программой, которая работает так, как ожидалось, и программой, которая попадает в бесконечный цикл. Итак, сегодня я использовал различные базовые математические выражения для REPL Java 9, JavaScript и Clojure и обнаружил несколько интересных фактов.

Самое интересное для меня, что Clojure понимает дроби! Итак, 9/5 — допустимое число в Clojure. Я могу печатать:

user=> (+ 9/7 9.0)
10.285714285714286

И получить действительный ответ от REPL. Но если я попробую ту же самую операцию в Java, я получу:

jshell> 9/7 + 9.0
$2 ==> 10.0

Хм!?! Ну, Java видит 9/7 как 9, деленное на 7, что оценивается как 1 в Java, потому что и 9, и 7 являются целыми значениями. Я могу заставить Java дать мне тот же ответ, что и Clojure, немного изменив ситуацию:

jshell> 9.0/7 + 9
$4 ==> 10.285714285714286

Между прочим, JavaScript находится где-то между Java и Clojure:

> 9/7
0.2857142857142858
> 9/7 + 9.0
10.285714285714286

Что все это значит? Я собираюсь взять этот язык за раз:

Clojure понимает и уважает дроби. Таким образом, 9/7 является допустимым числом по его правилам. И он уважает использование двойного (9.0) в утверждении, чтобы перевести все выражение в двойное перед его оценкой. Обратите внимание на разницу:

user=> (+ 9/7 9)
72/7
user=> (+ 9/7 9.0)
10.285714285714286

JavaScript упростил свой список типов до числового, логического и строкового, поэтому вместо того, чтобы понимать дробь, как Clojure, он просто оценивает дробь до десятичного значения, поэтому даже это дает мне результат с плавающей запятой:

> 9/7 + 9
10.285714285714286

Java, напротив, является строго типизированным и не будет оценивать выражение, как я ожидал, если я каким-то образом не скажу ему начать использовать двойные числа в начале оценки. Помните, вот что я видел:

jshell> 9/7 + 9.0
$2 ==> 10.0
jshell> 9.0/7 + 9
$4 ==> 10.285714285714286

Если я оставлю 9/7 в покое и сделаю последний элемент 9.0, Java обрабатывает 9/7 путем целочисленного деления, в результате чего получается 1, а затем добавляет 1 к 9,0, чтобы получить результат 10,0. Перемещая «.0» к первым 9, я говорю Java оценить 9.0/7 как двойное, и он автоматически обрабатывает остальную часть операции как двойную.