Синтаксис объявления переменных
От: x-code  
Дата: 04.04.21 21:06
Оценка:
Существует два распространенных варианта синтаксиса
"сначала тип" используется например в C/C++/Java/C#/D
int x;

и "сначала объект" используется например в Pascal/Go/Rust/Swift/Scala (с разными вариациями — двоеточия перед типом и т.п., еще важный момент — часто используются ключевые слова в начале, вроде var и let)
x int;


Современные языки имеют тенденцию ко второму варианту.
Почему? У него есть какое-то фундаментальное преимущество перед первым?

Про т.н. "most vexing parse" я знаю, это ошибка дизайна именно С/С++ и она не имеет прямого отношения к тому что тип идет первым, это скорее проблема того что функция начинается не с ключевого слова (func, fn) а с возвращаемого типа. Сложность с синтаксисом указателей на функции тоже с этим связана.

Все-же интересно, какие преимущества и недостатки есть у обоих способов объявления?
Re: Синтаксис объявления переменных
От: Pzz Россия https://github.com/alexpevzner
Дата: 04.04.21 21:17
Оценка:
Здравствуйте, x-code, Вы писали:

XC>Все-же интересно, какие преимущества и недостатки есть у обоих способов объявления?


Мне как-то попадалось объяснение, почему в Go сделано по второму варианту. Не сути, не ссылки я не помню, поищи сам.

Если учесть, что Go и C сделали примерно одни и те же люди, то их взгляд на вещи имеет значение.
Re: Синтаксис объявления переменных
От: torvic Голландия  
Дата: 04.04.21 21:19
Оценка: 2 (1)
Здравствуйте, x-code, Вы писали:

Одерски выбирал, потому что по его мнению имя важней типа и то что хорошо работало в си с короткими именами типов, спрячет его в скале за развесистой декларацией типа
Re: Types are moving to the right
От: Qbit86 Кипр
Дата: 04.04.21 21:21
Оценка: 2 (1) +1
Здравствуйте, x-code, Вы писали:

XC>"сначала объект" используется например в Pascal/Go/Rust/Swift/Scala


И в Kotlin: https://elizarov.medium.com/types-are-moving-to-the-right-22c0ef31dd4a

Глаза у меня добрые, но рубашка — смирительная!
Re: Синтаксис объявления переменных
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 04.04.21 21:23
Оценка: +1
Здравствуйте, x-code, Вы писали:

XC>Современные языки имеют тенденцию ко второму варианту.

XC>Почему? У него есть какое-то фундаментальное преимущество перед первым?

Да. Достаточно попытаться распарсить какой-нибудь int *(*fp)(float*[]) и описать, как это делается (выворачивать в уме все эти конструкции наизнанку).
Да даже typedef int *pint; реально надо прочитать как "pint = type pointer to int" и только после этого начинается понимание (даже если это в простом случае делается тривиально).
Это общее место учебников по C/C++ — при парсинге разворачиваешь эти описания задом наперёд.

XC>Про т.н. "most vexing parse" я знаю, это ошибка дизайна именно С/С++ и она не имеет прямого отношения к тому что тип идет первым, это скорее проблема того что функция начинается не с ключевого слова (func, fn) а с возвращаемого типа.


Совсем прямого — не имеет. Непрямое — имеет — что из-за кривого порядка var int x становятся неадекватными.

XC> Сложность с синтаксисом указателей на функции тоже с этим связана.


Именно с этим.
The God is real, unless declared integer.
Re[2]: Синтаксис объявления переменных
От: x-code  
Дата: 04.04.21 21:27
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Мне как-то попадалось объяснение, почему в Go сделано по второму варианту. Не сути, не ссылки я не помню, поищи сам.

Pzz>Если учесть, что Go и C сделали примерно одни и те же люди, то их взгляд на вещи имеет значение.

https://blog.golang.org/declaration-syntax
Там в основном упор на сложность объявления типов указателей на функции. Это правда, но это решается введением ключевого слова для функций и никакого отношения не имеет к тому, что в начале при объявлении — тип или объект.
Re: STLC
От: Qbit86 Кипр
Дата: 04.04.21 21:43
Оценка:
Здравствуйте, x-code, Вы писали:

XC>"сначала объект" используется например в Pascal/Go/Rust/Swift/Scala


Главное, что такая нотация используется в математике, например: https://en.wikipedia.org/wiki/Simply_typed_lambda_calculus
Оттуда уже её впитали все остальные языки (кроме Си-подобных).
Глаза у меня добрые, но рубашка — смирительная!
Re[2]: Синтаксис объявления переменных
От: x-code  
Дата: 04.04.21 21:44
Оценка:
Здравствуйте, netch80, Вы писали:

N>Да. Достаточно попытаться распарсить какой-нибудь int *(*fp)(float*[]) и описать, как это делается (выворачивать в уме все эти конструкции наизнанку).


Это имеет отношение к тому что тип вначале? Или это следствие того что для функции нет ключевого слова?
 (func(float*[]) int*)* fp;


N>Да даже typedef int *pint; реально надо прочитать как "pint = type pointer to int" и только после этого начинается понимание (даже если это в простом случае делается тривиально).


typedef вообще отдельная конструкция.
в С++ ввели using, правда странный синтаксис указателей на функции оставили, причем он еще и отличается от того что в typedef
typedef float (*func_ptr)(int);
using func_ptr = float (*)(int);


N>Совсем прямого — не имеет. Непрямое — имеет — что из-за кривого порядка var int x становятся неадекватными.


Вот тут непонятно, что за "var int x"?
Re[2]: Синтаксис объявления переменных
От: x-code  
Дата: 04.04.21 21:48
Оценка:
Здравствуйте, torvic, Вы писали:

T>Одерски выбирал, потому что по его мнению имя важней типа и то что хорошо работало в си с короткими именами типов, спрячет его в скале за развесистой декларацией типа


А насколько удобен синтаксис конструкторов с такой нотацией? Я не знаю Scala, но вот допустим на обычном си-подобном языке
Foo obj(1,2,"hello")
;
или
Foo obj = new Foo(1,2,"hello")
;

если всё это развернуть, то что получится?
obj(1,2,"hello") Foo;
или как-то так?
Re: Синтаксис объявления переменных
От: vsb Казахстан  
Дата: 04.04.21 21:54
Оценка: +2 -1
В первом варианте я пишу: User | и мне IDE уже подсказывает имя переменной user. Которое я и выберу, возможно с тем или иным суффиксом или префиксом. Т.к. очень часто имена переменных используют название типа. Во втором случае это уже так не работает.

Ещё один момент: если я не хочу указывать тип, я пишу var someVariable = .... Т.е. я заменяю название типа на var. Ну или на auto, let или другую подобную конструкцию. Это смотрится очень естественно и логично. Во втором варианте приходится писать этот var всегда, хоть я указываю тип, хоть нет. В этом в принципе есть и свои плюсы (все объявления переменных сразу выделяются) и минусы (лишняя писанина).
Re[3]: Синтаксис объявления переменных
От: vsb Казахстан  
Дата: 04.04.21 21:56
Оценка: +1
Здравствуйте, x-code, Вы писали:

T>>Одерски выбирал, потому что по его мнению имя важней типа и то что хорошо работало в си с короткими именами типов, спрячет его в скале за развесистой декларацией типа


XC>А насколько удобен синтаксис конструкторов с такой нотацией? Я не знаю Scala, но вот допустим на обычном си-подобном языке

XC>
Foo obj(1,2,"hello")
;

XC>или
XC>
Foo obj = new Foo(1,2,"hello")
;


XC>если всё это развернуть, то что получится?

XC>
obj(1,2,"hello") Foo;
или как-то так?


val obj1: Foo = new Foo(1, 2, "hello");
val obj2 = new Foo(1, 2, "hello"); // с автовыводом типа
Re: Синтаксис объявления переменных
От: varenikAA  
Дата: 05.04.21 04:19
Оценка: 2 (1) +1
Здравствуйте, x-code, Вы писали:

XC>Современные языки имеют тенденцию ко второму варианту.

XC>Почему? У него есть какое-то фундаментальное преимущество перед первым?
Думаю потому что современные ЯП осознали, что часто можно выполнить вывод типа из контекста.

let s = 42
// val s : int = 42


При этом двоеточие с типом читаю как уточнение типа переменной

let say (name : string) = Console.WriteLine("Hello, " + name)


Далее логически вытекает приведение типов


type Person(name) =
    class
        do printfn "Person name is %s" name
    end

type Worker(name) =
    class
        inherit Person(name)
        do printfn "Worker name is %s" name
    end

let person = Person("Bob")
let worker = Worker("Steve")
let steve = worker :> Person // успешное приведение к предку (вверх). ошибки не будет

try
    let bob = person :?> Worker
    None
with :? System.InvalidCastException as e ->
    printfn $"Ошибка приведение к потомку(вниз) {e.Message}"
    None
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: Синтаксис объявления переменных
От: varenikAA  
Дата: 05.04.21 04:21
Оценка: :)
Здравствуйте, x-code, Вы писали:


XC>
x int;


без двоеточия перед типом
даже хуже читается чем
XC>
int x;


Идеально:
name : string
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: Синтаксис объявления переменных
От: varenikAA  
Дата: 05.04.21 04:24
Оценка:
Здравствуйте, x-code, Вы писали:

XC>Все-же интересно, какие преимущества и недостатки есть у обоих способов объявления?


Источник истины:

(defgeneric description (object)
  (:documentation "Return a description of an object."))

(defmethod description ((object integer))
  (format nil "The integer ~D" object))

(defmethod description ((object float))
  (format nil "The float ~3,3f" object))


Т.е. сначала переменная, потом тип, т.к. тип определяется позже, сначала интерфейс
☭ ✊ В мире нет ничего, кроме движущейся материи.
Отредактировано 05.04.2021 4:25 Разраб . Предыдущая версия .
Re[3]: Синтаксис объявления переменных
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 05.04.21 07:29
Оценка: +1
Здравствуйте, x-code, Вы писали:

N>>Да. Достаточно попытаться распарсить какой-нибудь int *(*fp)(float*[]) и описать, как это делается (выворачивать в уме все эти конструкции наизнанку).


XC>Это имеет отношение к тому что тип вначале? Или это следствие того что для функции нет ключевого слова?

XC>
 (func(float*[]) int*)* fp;


Имеет к тому, что тип вначале.
Нет, не следствие.

N>>Да даже typedef int *pint; реально надо прочитать как "pint = type pointer to int" и только после этого начинается понимание (даже если это в простом случае делается тривиально).


XC>typedef вообще отдельная конструкция.


Она следует общему тренду языка. Если бы у него был тип справа, то было бы как во втором примере.

XC>в С++ ввели using, правда странный синтаксис указателей на функции оставили, причем он еще и отличается от того что в typedef

XC>
typedef float (*func_ptr)(int);
XC>using func_ptr = float (*)(int);


Это следствие того, что не смогли исправить до конца.

N>>Совсем прямого — не имеет. Непрямое — имеет — что из-за кривого порядка var int x становятся неадекватными.


XC>Вот тут непонятно, что за "var int x"?


Это если ты потребуешь добавлять var или func, но не сдвинешь тип вправо от переменной.
The God is real, unless declared integer.
Re[2]: STLC
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 05.04.21 07:34
Оценка: +3
Здравствуйте, Qbit86, Вы писали:

Q>Здравствуйте, x-code, Вы писали:


XC>>"сначала объект" используется например в Pascal/Go/Rust/Swift/Scala


Q>Главное, что такая нотация используется в математике, например: https://en.wikipedia.org/wiki/Simply_typed_lambda_calculus

Q>Оттуда уже её впитали все остальные языки (кроме Си-подобных).

C это тоже не первый источник, до этого был Algol, а до него Fortran.
В Fortran, похоже, источником явилось то, что писали

DIMENSION A(10,10)

для определения, что переменная — массив, а не скаляр, а дальше когда стали явно задавать типы — сделали по аналогии:

INTEGER XX
INTEGER YY(10,20)
The God is real, unless declared integer.
Re[4]: Синтаксис объявления переменных
От: x-code  
Дата: 05.04.21 08:09
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>
vsb>val obj1: Foo = new Foo(1, 2, "hello");
vsb>val obj2 = new Foo(1, 2, "hello"); // с автовыводом типа
vsb>


А если переменная стековая?
Re[5]: Синтаксис объявления переменных
От: vsb Казахстан  
Дата: 05.04.21 09:00
Оценка:
Здравствуйте, x-code, Вы писали:

vsb>>
vsb>>val obj1: Foo = new Foo(1, 2, "hello");
vsb>>val obj2 = new Foo(1, 2, "hello"); // с автовыводом типа
vsb>>


XC>А если переменная стековая?


В самом языке Scala такого понятия нет. В JVM на стеке могут храниться указатели и примитивные типы, поэтому я думаю, что код вида

var i: Int = 1


таки будет использовать стек, но это уже особенности оптимизации.
Re[5]: Синтаксис объявления переменных
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 05.04.21 09:17
Оценка:
Здравствуйте, x-code, Вы писали:

vsb>>
vsb>>val obj1: Foo = new Foo(1, 2, "hello");
vsb>>val obj2 = new Foo(1, 2, "hello"); // с автовыводом типа
vsb>>


XC>А если переменная стековая?


Escape analysis для ссылочных типов работает в полный рост.
The God is real, unless declared integer.
Re: Синтаксис объявления переменных
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 05.04.21 12:54
Оценка: 6 (2) +2
Здравствуйте, x-code, Вы писали:

XC>Современные языки имеют тенденцию ко второму варианту.

XC>Почему? У него есть какое-то фундаментальное преимущество перед первым?

По-моему, фундаментальных никаких нету. Просто в теории типов издавна было "x : T", потом так же было в языках ML семейства еще с 70х годов. А теперь авторы языков наконец открыли учебники/статьи и прониклись.

Кому как больше нравится, предпочтения чаще всего эстетические. К опциональности указания типов это отношения не имеет.
Что мне лично не очень нравится в нотации "тип справа":
x : T = v
выглядит как "х имеет тип (Т = v)". При том, что в некоторых языках вроде Idris "a = b" это вполне осмысленный тип.
И вообще, почему мы пишем T = v, когда имеем в виду x = v?

И еще лишний символ :, код аж на целую букву длиннее.

Когда типы слева, делать с функциями хтонический ужас как у Си никто не заставляет, конечно.

Я на работе занимаюсь созданием ЯП, и когда добавлял туда типы, сделал типы слева. Получилось довольно складно, имхо:
int x = 42
x = 42                   // тип можно и не указывать, он будет выведен
(a,b) => a+b             // лямбда, все типы выводятся
(int a, int b) => a+b    // лямбда с указанием типов аргументов
(a,b) => int: a+b        // лямбда с указанием типа результата
f(int a, int b) => a+b   // определение функции. заметьте, как легко
f(a, b) => int: a+b      //  превращать лямбду в ф-ю и обратно
inc(x) => int: x+1       //
(int) -> int g = inc     // переменная функционального типа, нет проблем его иметь слева
map((#a) -> #b f, [#a] xs) => ... // тут аргумент функ. типа, тоже все ок
Отредактировано 05.04.2021 12:57 D. Mon . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.