Вывод типа переменной
От: AlexCab LinkedIn
Дата: 04.05.11 16:37
Оценка:
В ходе изучения статическо типизации у меня возник вопрос, допустим:
SomeFunction(/*Аргументы строго определённого типа*/)
{
S VAR //Локальная перменная
//Какой то код
S = 0 //Присваевание числа
//Какой то код
S = "С" //Присваевание символа
//Какой то код
}
Возможно ли гарантировать отсутствие ошибки типа(отследить измение типа) в таком случае, если нет почему?
Спасибо.
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Re: Вывод типа переменной
От: WolfHound  
Дата: 04.05.11 16:59
Оценка:
Здравствуйте, AlexCab, Вы писали:

AC>Возможно ли гарантировать отсутствие ошибки типа(отследить измение типа) в таком случае, если нет почему?

Можно. Но не нужно.
В таком случае нужно давать ошибку компиляции.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Вывод типа переменной
От: Temoto  
Дата: 04.05.11 16:59
Оценка:
AC>В ходе изучения статическо типизации у меня возник вопрос, допустим:
AC> SomeFunction(/*Аргументы строго определённого типа*/)
AC> {
AC> S VAR //Локальная перменная
AC> //Какой то код
AC> S = 0 //Присваевание числа
AC> //Какой то код
AC> S = "С" //Присваевание символа
AC> //Какой то код
AC> }
AC>Возможно ли гарантировать отсутствие ошибки типа(отследить измение типа) в таком случае, если нет почему?
AC>Спасибо.

В вашем коде пока что и ошибок ещё нет, потому что вы не огласили правил, которые там могут быть нарушены. Может быть S VAR это union (variant), который может содержать значение разных типов и компилятор сумел доказать корректность работы с S как с числом между первым и вторым присваиванием, и как с символом после второго присваивания.

Пример:
S VAR
S = 0
X = S + 1
S = "C"
PRINT LOWER(S)

без изменения смысла транслируется в
S VAR
S = 0
X = S + 1

UNDEFINE S

S VAR
S = "C"
PRINT LOWER(S)


Но если воображаемый язык явно такое запрещает (что было бы очень хорошо), то отследить можно. Самый простой способ: в области видимости S найти все инструкции, которые могут изменять S (то есть присваивание и передача по ссылке) и проверить совместимость типов всех rvalue по порядку. При первой несовместимости — паника, type error.
Re: Вывод типа переменной
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.05.11 17:42
Оценка: -1
Здравствуйте, AlexCab, Вы писали:

AC>В ходе изучения статическо типизации у меня возник вопрос, допустим:

AC> SomeFunction(/*Аргументы строго определённого типа*/)
AC> {
AC> S VAR //Локальная перменная
AC> //Какой то код
AC> S = 0 //Присваевание числа
AC> //Какой то код
AC> S = "С" //Присваевание символа
AC> //Какой то код
AC> }
AC>Возможно ли гарантировать отсутствие ошибки типа(отследить измение типа) в таком случае, если нет почему?
AC>Спасибо.

Тут нет смысла рассуждать. Качай компилятор и интеграцию языка поддерживающего вывод типов (с блэкджекем и шлюхами) на практике и пробуй.

Менять тип изменяемой переменной не разумно, так как это будет маскировать ошибки. Nemerle выдаст сообщение об ошибке на второе использование. Плюс в Nemerle можно переопределять неизменяемые переменные (так называемые связывания):
def s = 0; // Неизменяемая переменная "s" инициализированная числом
// Какой то код 
def s = "С" // Другая неизменяемая переменная "s" инициализированная строкой
// Какой то код. В нем доступна только вторая переменная (типа строка).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Вывод типа переменной
От: AlexCab LinkedIn
Дата: 05.05.11 07:55
Оценка:
Здравствуйте, Temoto, Вы писали:

T>Может быть S VAR это union (variant), который может содержать значение разных типов...

Именно так.

T>Пример:

T>
T>S VAR
T>S = 0
T>X = S + 1
T>S = "C"
T>PRINT LOWER(S)
T>

T>без изменения смысла транслируется в
T>
T>S VAR
T>S = 0
T>X = S + 1
T>UNDEFINE S
T>S VAR
T>S = "C"
T>PRINT LOWER(S)
T>

T>Но если воображаемый язык явно такое запрещает (что было бы очень хорошо), то отследить можно.
Запрещает.

T>Самый простой способ: в области видимости S найти все инструкции, которые могут изменять S (то есть присваивание и передача по ссылке) и проверить совместимость типов всех rvalue по порядку. При первой несовместимости — паника, type error.

Спасибо, примерно так я и думал, компилятор может построить граф функции и обойти его проверяя типы, в случае неопределённости
например:
IF /*Какоето условие*/
    /        \
  S = "C"  S = 0
    \        /
     X = S + 1

Ошибка типов.
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Re[2]: Вывод типа переменной
От: AlexCab LinkedIn
Дата: 05.05.11 08:38
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD>Тут нет смысла рассуждать. Качай компилятор и интеграцию языка поддерживающего вывод типов (с блэкджекем и шлюхами) на практике и пробуй.

Есть в ToDo, но всему своё время.

VD>Менять тип изменяемой переменной не разумно, так как это будет маскировать ошибки.

Есть такая опасность, однако такой подход позволяет обходится меньшим количеством переменных, и упрощает код
например:
 //Определния
 W VAR //Переменная для промежуточного результата
 //Код
 /*Работа с числами*/
 /*Со строками*/
 /*И тп.*/

Читая далее код мы знаем что "W" используется для промежуточного результата.

VD>Nemerle выдаст сообщение об ошибке на второе использование.

На повтороное определение?

VD>Плюс в Nemerle можно переопределять неизменяемые переменные (так называемые связывания):

VD>
VD>def s = 0; // Неизменяемая переменная "s" инициализированная числом
VD>// Какой то код 
VD>def s = "С" // Другая неизменяемая переменная "s" инициализированная строкой
VD>// Какой то код. В нем доступна только вторая переменная (типа строка).
VD>

Примерно так, но и для изменяемых переменных, и без необходимости переопределять(более опасно, более удобно).
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Re[2]: Вывод типа переменной
От: AlexCab LinkedIn
Дата: 05.05.11 08:50
Оценка: :)
Здравствуйте, WolfHound, Вы писали:

WH>Можно. Но не нужно.

WH>В таком случае нужно давать ошибку компиляции.
Почему?
Я думаю используя такой подход можно отчасти упрастить код до уровня динамических языков,
при этом сохранив статисескую проверку типа.
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Re[3]: Вывод типа переменной
От: Lloyd Россия  
Дата: 05.05.11 10:19
Оценка:
Здравствуйте, AlexCab, Вы писали:

VD>>Менять тип изменяемой переменной не разумно, так как это будет маскировать ошибки.

AC>Есть такая опасность, однако такой подход позволяет обходится меньшим количеством переменных

Меньшее кол-во переменных в данном случае это скорее недостаток, а не достоинство.
Re[4]: Вывод типа переменной
От: AlexCab LinkedIn
Дата: 05.05.11 10:42
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, AlexCab, Вы писали:


VD>>>Менять тип изменяемой переменной не разумно, так как это будет маскировать ошибки.

AC>>Есть такая опасность, однако такой подход позволяет обходится меньшим количеством переменных
L>Меньшее кол-во переменных в данном случае это скорее недостаток, а не достоинство.
Why?
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Re[3]: Вывод типа переменной
От: 24  
Дата: 05.05.11 10:56
Оценка:
Здравствуйте, AlexCab, Вы писали:

AC>Есть такая опасность, однако такой подход позволяет обходится меньшим количеством переменных, и упрощает код

AC>например:
AC>
AC> //Определния
AC> W VAR //Переменная для промежуточного результата
AC> //Код
AC> /*Работа с числами*/
AC> /*Со строками*/
AC> /*И тп.*/
AC>

AC>Читая далее код мы знаем что "W" используется для промежуточного результата.

Это не упрощает, а усложняет код. В каждом месте употребления W не понятно сразу, что она может содержать — строку, или число, нужно смотреть предыдущие использования. Так можно и до одной глобальной переменной W "доупрощать", которую явно не нужно определять. Тут лучше разделить по отдельным функциям работу с числами и строками, тогда проблемы переиспользования переменной не возникнет.
Re[5]: Вывод типа переменной
От: artelk  
Дата: 05.05.11 11:23
Оценка:
Здравствуйте, AlexCab, Вы писали:

AC>Здравствуйте, Lloyd, Вы писали:


L>>Здравствуйте, AlexCab, Вы писали:


VD>>>>Менять тип изменяемой переменной не разумно, так как это будет маскировать ошибки.

AC>>>Есть такая опасность, однако такой подход позволяет обходится меньшим количеством переменных
L>>Меньшее кол-во переменных в данном случае это скорее недостаток, а не достоинство.
AC>Why?

Одно и то же имя имеет разный смысл в зависимости от позиции внутри функции. Это усложняет понимание.
Переопределение удобно только если тип меняется, а смысл переменной остается.
Приходит, например, в функцию строковой параметр itemCount. Ты знаешь, что там должно быть число.
В начале ф-ии парсишь его и переопределяешь itemCount с типом int:
f(itemCount : string) : void
{
  def itemCount = int.Parse(itemCount);
  //тут используем уже как число
}

Так да, удобно — чтобы лишние имена не плодить со всякими префиксами-постфиксами.
Пример, конечно, не очень, но иногда не хватает подобной фичи.
Re[4]: Вывод типа переменной
От: AlexCab LinkedIn
Дата: 05.05.11 12:13
Оценка:
Здравствуйте, 24, Вы писали:

24>Это не упрощает, а усложняет код.

Зависит от стиля кодирования, если подобные переменные используются именно для того для чего они были определены(промежуточного значения — для хранения промежуточного значения,
результата для результата, и тп.), и код разбит на не слишком большие блоки(всё на глазах) то проблем не возникает.

24>В каждом месте употребления W не понятно сразу, что она может содержать — строку, или число, нужно смотреть предыдущие использования.

В данном случае речь о небольших блоках кода(в несколько строк) в которых значение в W актуально.

24>Так можно и до одной глобальной переменной W "доупрощать", которую явно не нужно определять.

Нет, разумеется область видимости таких переменных ограничена телом функции где они определены.

24>Тут лучше разделить по отдельным функциям работу с числами и строками, тогда проблемы переиспользования переменной не возникнет.

Возникнет проблема с переиспользованием функций
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Re[6]: Вывод типа переменной
От: AlexCab LinkedIn
Дата: 05.05.11 12:25
Оценка:
Здравствуйте, artelk, Вы писали:
A>Одно и то же имя имеет разный смысл в зависимости от позиции внутри функции.
Смысл не меняется, например "переменная используемая для результата какой либо операции"
меняется содержимое переменной (не только значение но и тип значения, то есть может хранить значения разного типа).
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Re[5]: Вывод типа переменной
От: 24  
Дата: 05.05.11 12:31
Оценка:
Здравствуйте, AlexCab, Вы писали:

AC>если подобные переменные используются именно для того для чего они были определены(промежуточного значения — для хранения промежуточного значения,

AC>результата для результата, и тп.)
Эти переменные по-разному используются (в числовых расчётах и в строковых), зачем это смешивать?

AC>В данном случае речь о небольших блоках кода(в несколько строк) в которых значение в W актуально.

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

24>>Так можно и до одной глобальной переменной W "доупрощать", которую явно не нужно определять.

AC>Нет, разумеется область видимости таких переменных ограничена телом функции где они определены.
Почему? Если ввести неявную W, которая всегда означает "промежуточная переменная", то будет ещё "проще" — и писать меньше надо, увидел W — сразу знаешь — промежуточная.

24>>Тут лучше разделить по отдельным функциям работу с числами и строками, тогда проблемы переиспользования переменной не возникнет.

AC>Возникнет проблема с переиспользованием функций
Под переиспользованием я имел в виду повторное использование того же имени для других целей. Какая проблема с функциями?
Re[7]: Вывод типа переменной
От: artelk  
Дата: 05.05.11 13:19
Оценка:
Здравствуйте, AlexCab, Вы писали:

AC>Здравствуйте, artelk, Вы писали:

A>>Одно и то же имя имеет разный смысл в зависимости от позиции внутри функции.
AC>Смысл не меняется, например "переменная используемая для результата какой либо операции"
AC>меняется содержимое переменной (не только значение но и тип значения, то есть может хранить значения разного типа).

пример приведи
Re[6]: Вывод типа переменной
От: AlexCab LinkedIn
Дата: 05.05.11 13:40
Оценка:
Здравствуйте, 24, Вы писали:

24>Эти переменные по-разному используются (в числовых расчётах и в строковых), зачем это смешивать?

Суть в том что используются они одинаково(для одной цели), но не привязаны к типа хранимого значения.

24>И часто возникают ситуации, когда нужно больше одной промежуточной переменной в функции?

Зависит от предпочитаемого размера функций(у меня довольно часто, я разбиваю код на функции в среднем строк по 100-150).

AC>>Нет, разумеется область видимости таких переменных ограничена телом функции где они определены.

24>Почему?
Инкапсуляция.

24>Если ввести неявную W, которая всегда означает "промежуточная переменная", то будет ещё "проще" — и писать меньше надо, увидел W — сразу знаешь — промежуточная.

Такое я сделал ещё давно, можно определить набор переменных(или других объектов), их имена станут keywords, и использовать их по мере необходимости,
но у каждой функции тем не менее будет свой экземпляр такой переменой.

24>Под переиспользованием я имел в виду повторное использование того же имени для других целей. Какая проблема с функциями?

Я имел в виду увеличение количества собственно функций, и связанное с этим усложнение кода(при чтении прийдется прыгать от функции к функции, если нет комментариев
и не удалось понять по имени что делает функция).
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Re[3]: Вывод типа переменной
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.05.11 13:44
Оценка:
Здравствуйте, AlexCab, Вы писали:

VD>>Тут нет смысла рассуждать. Качай компилятор и интеграцию языка поддерживающего вывод типов (с блэкджекем и шлюхами) на практике и пробуй.

AC>Есть в ToDo, но всему своё время.

Это отговорки. Не помню кто сказал, но мне запомнилась одна фраза — "Вопрос приоритетов — это вопрос наличия желания. Если желания нет, то приоритет всегда будет низкий.". Очень точная фраза.

VD>>Менять тип изменяемой переменной не разумно, так как это будет маскировать ошибки.

AC>Есть такая опасность, однако такой подход позволяет обходится меньшим количеством переменных, и упрощает код

В наличии меньшего количества переменных нет ничего хорошего. На любом ФЯ можно писать почти совсем без переменных. Но это не значит, что код будет хорошо читаемым.
Так что не надо экономить на спичках. Если переменные нужны, то смело вводи их. А уж повторное использование имен — это просто глупость.

AC>например:

AC>
AC> //Определния
AC> W VAR //Переменная для промежуточного результата
AC> //Код
AC> /*Работа с числами*/
AC> /*Со строками*/
AC> /*И тп.*/
AC>

AC>Читая далее код мы знаем что "W" используется для промежуточного результата.

Ничего мы не знаем. Скорее всего в твоем коде будет море багов и найти их (из-за того, что ты сделал язык дырявым) будет очень не просто.

VD>>Nemerle выдаст сообщение об ошибке на второе использование.

AC> На повтороное определение?

Если это неизменяемые переменные, то не выдаст. Если первое определение было изменяемым, то выдаст предупреждение. Ну, а если попытаться одну переменную использовать для разных типов, то будет сообщение об ошибке.

AC>Примерно так, но и для изменяемых переменных, и без необходимости переопределять(более опасно, более удобно).


Для изменяемых переменных это опасно. В языках вроде С++ где такое переопределение возможно было не мало багов по невнимательности из-за этого. Так что на мой взгляд — это плохой дизайн.

Кроме того, как показывает практика, после некоторого периода привыкания в 99% случаев локальные переменные являются неизменяемыми. Так что проблем с этим просто не возникает.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Вывод типа переменной
От: Lloyd Россия  
Дата: 05.05.11 13:50
Оценка: +1
Здравствуйте, AlexCab, Вы писали:

A>>Одно и то же имя имеет разный смысл в зависимости от позиции внутри функции.

AC>Смысл не меняется, например "переменная используемая для результата какой либо операции"

Если пойти по этой дорожке дальше, то у всех переменных один смысл — зранение значения.

AC>меняется содержимое переменной (не только значение но и тип значения, то есть может хранить значения разного типа).


Содержимое и определяет семантику переменной.
Re[7]: Вывод типа переменной
От: 24  
Дата: 05.05.11 14:04
Оценка:
Здравствуйте, AlexCab, Вы писали:

24>>Эти переменные по-разному используются (в числовых расчётах и в строковых), зачем это смешивать?

AC>Суть в том что используются они одинаково(для одной цели), но не привязаны к типа хранимого значения.
С таким же успехом можно сказать, что вообше все переменные используются для одной цели — хранения значений.

24>>Если ввести неявную W, которая всегда означает "промежуточная переменная", то будет ещё "проще" — и писать меньше надо, увидел W — сразу знаешь — промежуточная.

AC>Такое я сделал ещё давно, можно определить набор переменных(или других объектов), их имена станут keywords, и использовать их по мере необходимости,
AC>но у каждой функции тем не менее будет свой экземпляр такой переменой.
Имхо, просто "промежуточные" переменные без какой-либо логической нагрузки нужны крайне редко, и для этого не стоит вводить отдельное ключевое слово. Осмысленные же промежуточные значения получают свои имена.

24>>Под переиспользованием я имел в виду повторное использование того же имени для других целей. Какая проблема с функциями?

AC>Я имел в виду увеличение количества собственно функций, и связанное с этим усложнение кода(при чтении прийдется прыгать от функции к функции, если нет комментариев
AC>и не удалось понять по имени что делает функция).
С короткими функциями (до одной экранной страницы) очень редко возникают ситуации, когда из названия сложно понять, что функция делает. Если не знаешь, как назвать функцию — первый признак того, что с ней что-то не так.
Re[8]: Вывод типа переменной
От: AlexCab LinkedIn
Дата: 05.05.11 14:28
Оценка:
Здравствуйте, artelk, Вы писали:
AC>>Смысл не меняется, например "переменная используемая для результата какой либо операции"
AC>>меняется содержимое переменной (не только значение но и тип значения, то есть может хранить значения разного типа).
A>пример приведи
//Определения 
 Handle VAR
//Работаем с окном
 Handle = GetWindowHandle()
 PostMessage(Handle)
 /*Делаем что то ещё с окном*/
//Работаем с потоком
 Handle = GetThreadHandle()
 PostThreadMessage(Handle)
 /*Делаем что то ещё с потоком*/
 PostMessage(Handle) //<-- Ошибка типа
Между тем,что я думаю,тем,что я хочу сказать,тем,что я,как мне кажется,говорю,и тем,что вы хотите услышать,тем,что как вам кажется,вы слышите,тем,что вы понимаете,стоит десять вариантов возникновения непонимания.Но всё-таки давайте попробуем...(Э.Уэллс)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.