Oberon space
General Category => Общий раздел => Тема начата: valexey_u от Ноябрь 01, 2016, 01:04:14 am
-
Продолжаем нашу рубрику неочевидных ошибок в программах на разных ЯП. На этот раз у нас будет строго статически типизированный функциональный язык - Ocaml.
Итак, вот функция, которая успешно компилируется, запускается, но выдает неверный результат (должна искать индекс минимального элемента массива):
let min_index a =
let min i m =
let m = if a.(i) < a.(m) then i else m in
if (Array.length a) = (i+1) then
m
else
min (i+1) m
in
min 0 0
Надо найти ошибку и ее исправить.
-
А если так:
let min_index a =
let min i m =
let m2 = if a.(i) < a.(m) then i else m in
if (Array.length a) = (i+1) then
m2
else
min (i+1) m2
in
min 0 0
-
А если так:
let min_index a =
let min i m =
let m2 = if a.(i) < a.(m) then i else m in
if (Array.length a) = (i+1) then
m2
else
min (i+1) m2
in
min 0 0
Неа.
-
Видимо, так как у функции min отсутствет указание рекурсивности rec, то при вызове min внутри min приведет к вызову предопределенной функции min
-
Видимо, так как у функции min отсутствет указание рекурсивности rec, то при вызове min внутри min приведет к вызову предопределенной функции min
Да. Верно. указание рекурсивности rec приводит к изменению области видимости идентификатора данной функции. По умолчанию (без rec) идентификатор функции внутри самой функции не виден, поэтому рекурсивный вызов не возможен.
Подобные приколы также могут произойти не только с предопределенными функциями (входящими в автоимпортируемый модуль Pervasives ( https://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html ) но и с функциями из других библиотечных модулей если их "импортируешь" через open. В окамле по умолчанию доступны все модули без импортов, просто к сущностям модулей нужно обращаться явно квалифицировав имя модуля. Использовав же open Modulename мы помещаем все сущности модуля Modulename в наш неймспейс (также как предопределенные функции и типы). Со всеми вытекающими.
Поэтому open используют редко. Ну а чтобы узнать какие именно модули использует данный модуль, можно воспользоваться соответствующей стандартной утилитой. Блока импортов там нет.
-
Ну пипец какой-то. И компилятор не предупреждает о таком переопределении? Что за аццкий ацтой?