FR>>При реализации метода интерфейса в классе, тело метода из интерфейса будет вызыватся как предусловие.
К>Т.е. идеи Мейера, но с несколько другой (более гибкой) системой чтипизации?
Угу. Но просто котрактное программирование и сейчас на питоне можно сделать, есть несколько библиотек, синтаксически немного коряво конечно но работает. интересно именно что из всего этого в комплексе получится. Если конечно не отменят. Пока в планах на python 3.0 написано так:
(Maybe) add optional declarations for static typing
Re[4]: Как скрестить ужа и ежа или статическую и утиные типи
E>В Скале накрутили нехилую иерархию типов, в которой есть общий корень scala.Any (все наследники от него) и общий крайний scala.Nothing (который является наследником от всех). И для того, чтобы параметризованные методы могли работать с родственными типами там понапридумывали разных ко- и контра-вариантностей, ограничений на типы параметров сверху и снизу... В общем, лично у меня в голове не укладывается
E>Как бы в следующем Питоне не получить чего-нибудь подобного.
Да такая проблема есть и требует разруливания, ван Россум только обозначил ее, про то как хочет разрешить ни слова.
Re[4]: Как скрестить ужа и ежа или статическую и утиные типи
Здравствуйте, FR, Вы писали:
FR>Нет класс как был так и остается. FR>А тип абстактное понятие, важное только например при объявлении функции. Мы можем объявить функцию принимающую определенный интерфейс, так вот любой класс у которого есть все функции с сигнатурой соответствующей этому интерфейсу будет принят, иначе отвергнут (в момент компиляции или runtime исключение). В отличии от статических языков при этом утиная типизация остается в силе, класс не обязан наследоватся от данного интерфейса, нужно только чтобы он ему соответствовал.
Это называется утянуть идею у Хаскеля. Надо признать, что в Хаскеле идея классов типов довольно разумна. Как я понимаю разница в основном заключается в том, что в хаскеле надо явно описывать воплощения классов типов для конкретных типов, а Питоне этот процесс будет не явным.
Хаскеле для вывода базовго типа требующегося функции используются ограничения на имена идентификаторов налогаемые системой типов Хиндли-Миллера. Это ограничение с оной стороны запрещает перегрузку методов по имени, но с другой предоставляет полностью автоматический вывод типов. В Питоне ограничения а-ля Хидли-Силлер явно не пройдет. Стало быть вывод типов будет сильно ограничен. Это скорее всего привдет к тому, что весь контроль будет осуществляться в рантайме. А тогда не ясно ради чего затевается игр? И стоит ли она свеч?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Как скрестить ужа и ежа или статическую и утиные типи
Здравствуйте, FR, Вы писали:
FR>Да еще вот это совокупность классов соответствующих даному интерфейсу и есть тип. То есть понятие абстрактное и расширяемое.
Ерунда получается. Интерфейс (в понимании Явы/Шарпа) в такой системе и должен быть 1 в 1 равен классу. А разница должна заключаться тольк в том, что сопоставление кокретного объекта и этого интерфейса/класса должно производитья неявно.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Это называется утянуть идею у Хаскеля. Надо признать, что в Хаскеле идея классов типов довольно разумна. Как я понимаю разница в основном заключается в том, что в хаскеле надо явно описывать воплощения классов типов для конкретных типов, а Питоне этот процесс будет не явным.
Ну питон традиционно оттуда разные вещи утягивает
VD>Хаскеле для вывода базовго типа требующегося функции используются ограничения на имена идентификаторов налогаемые системой типов Хиндли-Миллера. Это ограничение с оной стороны запрещает перегрузку методов по имени, но с другой предоставляет полностью автоматический вывод типов. В Питоне ограничения а-ля Хидли-Силлер явно не пройдет. Стало быть вывод типов будет сильно ограничен. Это скорее всего привдет к тому, что весь контроль будет осуществляться в рантайме. А тогда не ясно ради чего затевается игр? И стоит ли она свеч?
Ты статью внимательнее почитай, там есть про мотивировку и там нет цели выводить все во время компиляции.
Re[6]: Как скрестить ужа и ежа или статическую и утиные типи
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, FR, Вы писали:
FR>>Да еще вот это совокупность классов соответствующих даному интерфейсу и есть тип. То есть понятие абстрактное и расширяемое.
VD>Ерунда получается. Интерфейс (в понимании Явы/Шарпа) в такой системе и должен быть 1 в 1 равен классу.
Ну у ван Россумма интерфейс понятие более широкое чем в Шарпе, он хочет под интерфейс подвести не только сигнатуру но и контракт.
VD>А разница должна заключаться тольк в том, что сопоставление кокретного объекта и этого интерфейса/класса должно производитья неявно.
Так эта разница как раз и дает возможность легко делать обобщенные функции, так что реально это очень большая разница.
Re[5]: Как скрестить ужа и ежа или статическую и утиные типи
Здравствуйте, Курилка, Вы писали:
К>А что тебя в этом пугает? Наоборот всё логично. К>И вариантности там в тему вполне.
Логично это все кажется во время чтения ScalaOverview и ScalaByExample, но когда берешься за ScalaReference... В общем "ниасилил". Тем более, что довольно-таки пространное объявление:
def min[ T < Ordered[T] ]( a: T, b: T ) : T =
if( a < b ) a else b
все равно не спасает, когда требуется вызвать min для float и double. Как в свое время в C++ произошло, когда вместо С-шных макросов min/max, появились шаблонные функции std::min/std::max. И часть кода (например, когда сравнивались int и long или int и float) элементарно перестала работать.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: Как скрестить ужа и ежа или статическую и утиные типизац
Здравствуйте, AndreiF, Вы писали:
AF>Здравствуйте, FR, Вы писали:
FR>>Мне показались очень интересными некторые его рассуждения, вскрывающие и некторые недостатки статической типизации.
AF>Тема недостатков статической типизации не раскрыта.
Так вроде все на поверхности, но недостатки не вообще статической типизации а схемы "тип == класс" которая ограничена и менее общая чем схема "тип по сигнатуре", по второй схеме обобщенные функции вводятся легко и естественно. Ну и кроме того обозначены и некторые проблемы которые например в том же окамле (а он типизирован по второй схеме) не разрешены.
Re[8]: Как скрестить ужа и ежа или статическую и утиные типи
FR>То есть это шире чем объектные классы окамла. Те же интерфейсы у ван Россума включают не только сигнатуры методов но и тела, что позволяет в интерфейсе прописывать и Design By Contract и вообще более жесткие ограничения.
Товарищи поставившие минус счем не согласны то?
Re[6]: Как скрестить ужа и ежа или статическую и утиные типи
Здравствуйте, eao197, Вы писали:
E>все равно не спасает, когда требуется вызвать min для float и double. Как в свое время в C++ произошло, когда вместо С-шных макросов min/max, появились шаблонные функции std::min/std::max. И часть кода (например, когда сравнивались int и long или int и float) элементарно перестала работать.
Интересно надо посмотреть как в скала это сделано.
По любому при такой типизации надо или заводить как бы вторую иреархию уже не классов а типов, или вводить для каждого типа числовой приоритет который будет учитыватся при разрешении типов.
Re[7]: Как скрестить ужа и ежа или статическую и утиные типи
E>>def min[ T < Ordered[T] ]( a: T, b: T ) : T =
E>> if( a < b ) a else b
E>>
E>>все равно не спасает, когда требуется вызвать min для float и double.
LCR>Не понял. А что мешает вызывать min для double? Ordered, насколько мне известно, определён для всех чисел.
Коля, тут вообще засада оказалась. Классы scala.Float, scala.Double и пр. не имеют примеси Ordered, поэтому использование их в сочетании с приведенной выше реализацией min нельзя вообще, т.к. не выполняется ограничение для типа [T <: Ordered[T]]. Есть еще классы scala.runtime.RichFloat, scala.runtime.RichDouble, которые имеют примесь Ordered, но -- для RichFloat это примесь Ordered[scala.Float]. Так что ограничение [T<:Ordered[T]] опять не выполняется, поскольку T -- это RichFloat, но он не производен от Ordered[RichFloat]. В общем кому-как, а мне такие заморочки с типами запоминать не хочется.
Но изначально я говорил вот о чем. Допустим, у нас есть тип T, который удовлетворяет условию [T<:Ordered[T]]. И есть тип U, который удовлетворяет условию [U<:Ordered[U]]. И пусть они не связаны друг с другом отношениями наследования. Например, BcdNumer (двоично десятичное число) и SimpleFraction (простая дробь, вида 1/3, 5/7 и т.д.). Сравнить объекты BcdNumber и SimpleFraction с помощью такого min невозможно, ведь мы нуждаемся в объектах одного типа T. Добавление в min двух типов-параметров ситуацию не исправляет, поскольку:
a) сигнатура a.< (которая берется из Ordered) не совпадает с нужной нам, т.к. аргументом a.< будет объект b типа U, а не T;
b) возвращать придется не T и не U, а scala.Any.
Между тем, в динамически типизированных языках без анотаций типов (в том же Ruby к примеру), написать min, который позволяет сравнивать BcdNumer и SimpleFraction не так уж и сложно. Причем возвращаться будет объект подходящего типа:
class BcdNumber
def initialize( v )
@value = v
end
def to_int
@value
end
def to_f
@value.to_f
end
def to_s
"bcd:#{@value}"end
def <(other)
if other.respond_to?( :to_f )
@value.to_f < other.to_f
elsif other.respond_to?( :to_int )
@value < other.to_int
else
fail "unable to compare #{self} with #{other}"end
end
end
class SimpleFraction
def initialize( dividend, divisor )
@dividend, @divisor = dividend, divisor
end
def to_f
@dividend.to_f / @divisor
end
def to_s
"(#{@dividend}/#{@divisor})"end
def <(other)
if other.respond_to?( :to_f )
self.to_f < other.to_f
else
fail "unable to compare #{self} with #{other}"end
end
end
def min(a, b)
if a < b then a else b end
end
b = BcdNumber.new( 5 )
s = SimpleFraction.new( 1, 3 ) # 1/3
puts min( b, 6 )
puts min( b, 4 )
puts min( b, 4.99 )
puts min( b, 5.01 )
puts min( b, s )
puts min( s, b )
puts min( s, 0.2 )
puts min( s, 0.34 )
что дает при запуске:
bcd:5
4
4.99
bcd:5
(1/3)
(1/3)
0.2
(1/3)
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: Как скрестить ужа и ежа или статическую и утиные типи
Здравствуйте, FR, Вы писали:
FR>Так вроде все на поверхности, но недостатки не вообще статической типизации а схемы "тип == класс" которая ограничена и менее общая чем схема "тип по сигнатуре", по второй схеме обобщенные функции вводятся легко и естественно.
Насколько я помню, такая техника называется interface inference и уже применяется в других языках. Со схемой "тип=класс" она никак не конфликтует, на самом деле, и их можно благополучно применять одновременно.
FR>Ну и кроме того обозначены и некторые проблемы которые например в том же окамле (а он типизирован по второй схеме) не разрешены.
Э... не уточнишь, какие именно?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Как скрестить ужа и ежа или статическую и утиные типи
Здравствуйте, eao197, Вы писали:
E>Но изначально я говорил вот о чем. Допустим, у нас есть тип T, который удовлетворяет условию [T<:Ordered[T]]. И есть тип U, который удовлетворяет условию [U<:Ordered[U]]. И пусть они не связаны друг с другом отношениями наследования. Например, BcdNumer (двоично десятичное число) и SimpleFraction (простая дробь, вида 1/3, 5/7 и т.д.). Сравнить объекты BcdNumber и SimpleFraction с помощью такого min невозможно, ведь мы нуждаемся в объектах одного типа T. Добавление в min двух типов-параметров ситуацию не исправляет, поскольку: E>a) сигнатура a.< (которая берется из Ordered) не совпадает с нужной нам, т.к. аргументом a.< будет объект b типа U, а не T; E>b) возвращать придется не T и не U, а scala.Any.
Ммм, я в Скале не до конца разбираюсь, но разве тут не будут использоваться неявные преобразования? Чтобы получить из T U или наоборот?
Re[7]: Как скрестить ужа и ежа или статическую и утиные типи
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, eao197, Вы писали:
E>>все равно не спасает, когда требуется вызвать min для float и double. Как в свое время в C++ произошло, когда вместо С-шных макросов min/max, появились шаблонные функции std::min/std::max. И часть кода (например, когда сравнивались int и long или int и float) элементарно перестала работать.
FR>Интересно надо посмотреть как в скала это сделано. FR>По любому при такой типизации надо или заводить как бы вторую иреархию уже не классов а типов, или вводить для каждого типа числовой приоритет который будет учитыватся при разрешении типов.
Насколько я знаю, там для этого используются view, которые есть что-то типа преобразователей исходного типа в нужный.
Re[4]: Как скрестить ужа и ежа или статическую и утиные типи
Здравствуйте, AndreiF, Вы писали:
AF>Здравствуйте, FR, Вы писали:
FR>>Так вроде все на поверхности, но недостатки не вообще статической типизации а схемы "тип == класс" которая ограничена и менее общая чем схема "тип по сигнатуре", по второй схеме обобщенные функции вводятся легко и естественно.
AF>Насколько я помню, такая техника называется interface inference и уже применяется в других языках. Со схемой "тип=класс" она никак не конфликтует, на самом деле, и их можно благополучно применять одновременно.
А нет чего-нибудь серьёзного под рукой на эту тему?
Re[4]: Как скрестить ужа и ежа или статическую и утиные типи
Здравствуйте, AndreiF, Вы писали:
AF>Здравствуйте, FR, Вы писали:
FR>>Так вроде все на поверхности, но недостатки не вообще статической типизации а схемы "тип == класс" которая ограничена и менее общая чем схема "тип по сигнатуре", по второй схеме обобщенные функции вводятся легко и естественно.
AF>Насколько я помню, такая техника называется interface inference и уже применяется в других языках. Со схемой "тип=класс" она никак не конфликтует, на самом деле, и их можно благополучно применять одновременно.
Конечно не конфликтует потому что в этих языка уже тип != класс.
FR>>Ну и кроме того обозначены и некторые проблемы которые например в том же окамле (а он типизирован по второй схеме) не разрешены.
AF>Э... не уточнишь, какие именно?
Да те же самые про которые пишет выше eao197 и которые затронуты у ван Россума, и нерешение которых в окамле привело к уродцам типа '.+'
Re[9]: Как скрестить ужа и ежа или статическую и утиные типи
Здравствуйте, Курилка, Вы писали:
К>Ммм, я в Скале не до конца разбираюсь,
Я, кстати, то же. Поскольку не выдержал штудирования ScalaReference где-то на половине.
Может быть, будь по Скале какое-нибудь фундаментальное введение в язык, вроде Programming Ruby 2nd Дейва Томаса или хотя бы "Язык программирования C++" Страуструпа, все было бы и не так страшно. Но изучать язык по его спецификации, написанной на сухом математическом языке -- можно застрелиться. Ко- и контра- вариантности я еще как-то понимал. Но когда в дело еще начала вмешиваться линеаризация классов/примесей (причем выполняющаяся справа на лево), да добавились view я просто сдался
К> но разве тут не будут использоваться неявные преобразования? Чтобы получить из T U или наоборот?
Они будут использоваться только, если в прототипе min указать, что какой-то и параметров может быть выведен неявно. Но, если кто-то зафиксировал min в простом варианте, без implicit спецификаций, то ничего уже не сделать. AFAIK.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.