Здравствуйте, eao197, Вы писали:
K>>И это, по-вашему, разница по форме или по содержанию? E>По содержанию. E>Вызов f() вместо f.call() -- это синтаксический сахар. E>Но вот инструкция agent вместо ручного инстанцирования интерфейса -- это уже не синтаксический сахар.
А какой критерий?
Разница между foo(bar) и foo(agent bar) — это синтаксический сахар или нет?
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, eao197, Вы писали:
E>Если вы пропустите скомпилированный код через jad, то увидите, что конструкции f.getClass и foo.getClass применяются не к функциям, а к специальным объектам, которые Nice создает для хранения ссылок на эти функции.
Вообще-то это детали реализации.
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, eao197, Вы писали:
E>Я по ходу этой дискуссии попробовал получить в качестве функции метод объекта в Nice -- и не нашел как. Т.е., в случае со свободной функцией: E>
E>int inc( int a ) = a + 1;
E>void main( String[] args ) {
E> let f = inc;
E>}
E>
E>f -- это всегда (int)->int. Но в случае с объектом: E>
E>class A {
E> int inc( int a ) = a + 1;
E>}
E>void main( String[] args ) {
E> let o = new A();
E> let f = o.f; // вы, конечно, имели в виду o.inc
E>}
E>
class A {
int inc(int a ) = a + 1;
}
void main( String[] args ) {
let o = new A();
let i = o.inc(1);
let f = inc; // вот как это делается
let j = f(o, 1);
println(i == j);
}
выводит true
Просто o.inc воспринимается как inc(o, ?), а частичного применения, как я понял, в Nice нет. Жалко, конечно, но жизнь есть жизнь.
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, eao197, Вы писали:
K>>>В Nice ссылка не называется функцией. Ссылки как отдельной сущности в Nice (как и в Java), насколько я понимаю, нет. E>>Переменная, ссылающаяся на ссылочный тип или аргумент функции, ссылающийся на ссылочный тип, или атрибут класса, ссылающийся на ссылочный тип -- это все ссылки. Как в Nice, так и в Java.
K>Разница между языком со ссылками и языком со ссылочными типами в данном случае в том, что в первом можно и нужно явно указывать способ передачи — по ссылке или по значению, а во втором это определяется свойствами типа. K>Можно ли в D передать объект по значению? Или только по ссылке?
В D, как и в C#, типы делятся на reference type (классы) и value type (структуры и элементарные типы). Соответственно экземпляры reference-типов передаются либо по ссылке, либо по указателю, но не по значению. А экземпляры value-типов передаются либо по значению, либо по указателю, но ссылок для них в D нет.
K>И да, кстати, является ли тип RT delegate(T) типом всех видов функций T->RT в D (т.е. экземплярных, статических, свободных)?
Насколько я знаю -- да.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
K>class A {
K> int inc(int a ) = a + 1;
K>}
K>void main( String[] args ) {
K> let o = new A();
K> let i = o.inc(1);
K> let f = inc; // вот как это делается
K> let j = f(o, 1);
K> println(i == j);
K>}
K>
K>выводит true
Теперь добавте в область видимости еще несколько объектов с методом inc или свободных функций inc.
И почему, внутри класса A метод inc имеет сигнатуру (int)->int, а вне -- (A,int)->int? Это, вообще-то говоря, разные функции. Ведь, например, если я имею некую HOF, который ожидает функцию вида (int)->int, то я не смогу передать в него метод inc именно объекта o.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, eao197, Вы писали:
K>>>И это, по-вашему, разница по форме или по содержанию? E>>По содержанию. E>>Вызов f() вместо f.call() -- это синтаксический сахар. E>>Но вот инструкция agent вместо ручного инстанцирования интерфейса -- это уже не синтаксический сахар.
K>А какой критерий?
Мое субъективное восприятие синтаксического сахара.
K>Разница между foo(bar) и foo(agent bar) — это синтаксический сахар или нет?
Нет.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
K>>class A {
K>> int inc(int a ) = a + 1;
K>>}
K>>void main( String[] args ) {
K>> let o = new A();
K>> let i = o.inc(1);
K>> let f = inc; // вот как это делается
K>> let j = f(o, 1);
K>> println(i == j);
K>>}
K>>
K>>выводит true
E>Теперь добавте в область видимости еще несколько объектов с методом inc или свободных функций inc. E>И почему, внутри класса A метод inc имеет сигнатуру (int)->int, а вне -- (A,int)->int?
Это только сахар. В Nice вообще нет, фактически, обычных методов. Любой метод — частный случай мультиметода. Диспетчеризация-то множественная, в общем случае.
Фактически нет разницы между
class A {
int inc(int a ) = a + 1;
}
И
class A {
}
int inc(A t, int a) = a + 1;
E>Это, вообще-то говоря, разные функции.
В том-то и дело, что нет.
E>Ведь, например, если я имею некую HOF, который ожидает функцию вида (int)->int, то я не смогу передать в него метод inc именно объекта o.
Точно. Частичного применения-то нет. Нужно писать так: curry(method_name)(object_variable)
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, eao197, Вы писали:
K>>Разница между языком со ссылками и языком со ссылочными типами в данном случае в том, что в первом можно и нужно явно указывать способ передачи — по ссылке или по значению, а во втором это определяется свойствами типа. K>>Можно ли в D передать объект по значению? Или только по ссылке? E>В D, как и в C#, типы делятся на reference type (классы) и value type (структуры и элементарные типы). Соответственно экземпляры reference-типов передаются либо по ссылке, либо по указателю, но не по значению.
И & явно указывается?
E>А экземпляры value-типов передаются либо по значению, либо по указателю, но ссылок для них в D нет.
K>>И да, кстати, является ли тип RT delegate(T) типом всех видов функций T->RT в D (т.е. экземплярных, статических, свободных)? E>Насколько я знаю -- да.
There are no pointers-to-members in D, but a more useful concept called delegates are supported. Delegates are an aggregate of two pieces of data: an object reference and a function pointer. The object reference forms the this pointer when the function is called.
Delegates are declared similarly to function pointers, except that the keyword delegate takes the place of (*), and the identifier occurs afterwards:
int function(int) fp; // fp is pointer to a functionint delegate(int) dg; // dg is a delegate to a function
The C style syntax for declaring pointers to functions is also supported:
int (*fp)(int); // fp is pointer to a function
A delegate is initialized analogously to function pointers:
int func(int);
fp = &func; // fp points to funcclass OB
{ int member(int);
}
OB o;
dg = &o.member; // dg is a delegate to object o and
// member function member
Delegates cannot be initialized with static member functions or non-member functions.
Delegates are called analogously to function pointers:
fp(3); // call func(3)
dg(3); // call o.member(3)
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Klapaucius, Вы писали:
K>Фактически нет разницы между K>
K>class A {
K> int inc(int a ) = a + 1;
K>}
K>
K>И K>
K>class A {
K>}
K>int inc(A t, int a) = a + 1;
K>
Между этими нет. Но проблема не в этом, а в том, что имея в одной области видимости:
class A { int inc(int a) = ... }
class B { int inc(int a) = ... }
int inc(int a) = ...;
В Nice не видно способа сделать выбор в пользу какого то из них.
E>>Это, вообще-то говоря, разные функции.
K>В том-то и дело, что нет.
Ну я не знаю, как, в принципе, (int)->int может быть тем же самым, что и (A, int)->int. Это разные функции и, как вы сами показали ниже, нужно вручную приводить одно к другому.
E>>Ведь, например, если я имею некую HOF, который ожидает функцию вида (int)->int, то я не смогу передать в него метод inc именно объекта o.
K>Точно. Частичного применения-то нет. Нужно писать так: curry(method_name)(object_variable)
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, eao197, Вы писали:
K>>>Разница между языком со ссылками и языком со ссылочными типами в данном случае в том, что в первом можно и нужно явно указывать способ передачи — по ссылке или по значению, а во втором это определяется свойствами типа. K>>>Можно ли в D передать объект по значению? Или только по ссылке? E>>В D, как и в C#, типы делятся на reference type (классы) и value type (структуры и элементарные типы). Соответственно экземпляры reference-типов передаются либо по ссылке, либо по указателю, но не по значению.
K>И & явно указывается?
Где именно?
Вот как работают ссылочные типы в D:
class Demo { ... }
void f( Demo d ) {
// d -- это ссылка на экземпляр Demo.
}
void g() {
Demo o = new Demo; // o -- это ссылка на экземпляр Demo.
f( o ); // Передача по ссылке.
}
E>>А экземпляры value-типов передаются либо по значению, либо по указателю, но ссылок для них в D нет.
K>>>И да, кстати, является ли тип RT delegate(T) типом всех видов функций T->RT в D (т.е. экземплярных, статических, свободных)? E>>Насколько я знаю -- да.
K>Я уже нашел здесь.
Просуммировать то, что там написано можно так:
— свободные функции и статические методы -- это R function(A);
— методы объектов и вложенные функции -- это R delegate(A).
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, eao197, Вы писали:
E>>Если вы пропустите скомпилированный код через jad, то увидите, что конструкции f.getClass и foo.getClass применяются не к функциям, а к специальным объектам, которые Nice создает для хранения ссылок на эти функции.
K>Вообще-то это детали реализации.
Это было бы деталями реализации, если бы у Nice была спецификация языка и несколько независимых реализаций компиляторов. А в данном случае это всего лишь демонстрация того, что при необходимости представления ссылки на функцию Nice прибегает к тем же средствам, что и Eiffel -- конструированию объекта, содержащего ссылку на функцию/метод. И того, что foo.getClass -- это обращение не к функции (т.е. функция не является объектом, в чем сомневался VoidEx), а к неявно сконструированному объекту, содержащему ссылку на функцию.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
E>class A { int inc(int a) = ... }
E>class B { int inc(int a) = ... }
E>int inc(int a) = ...;
E>
E>В Nice не видно способа сделать выбор в пользу какого то из них.
class A {
int inc(int a ) = a + 1;
}
int inc(int a) = a + 1;
void main( String[] args ) {
let o = new A();
let i = o.inc(1);
(A, int)->int f = inc;
let j = f(o, 1);
println(i == j);
}
E>Ну я не знаю, как, в принципе, (int)->int может быть тем же самым, что и (A, int)->int.
И почему, внутри класса A метод inc имеет сигнатуру (int)->int, а вне -- (A,int)->int? Это, вообще-то говоря, разные функции.
Еще раз. Метод имеет сигнатуру (A,int)->int. Внутри он, снаружи — это не важно. просто первый аргумент может в некоторых случаях быть неявным.
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, eao197, Вы писали:
E>Вот как работают ссылочные типы в D: E>
E>class Demo { ... }
E>void f( Demo d ) {
E> // d -- это ссылка на экземпляр Demo.
E>}
E>void g() {
E> Demo o = new Demo; // o -- это ссылка на экземпляр Demo.
E> f( o ); // Передача по ссылке.
E>}
E>
Странно. Если функцию все равно можно передать только по ссылке, зачем это указывать явным образом? Ситуация с объектами гораздо логичнее.
K>>Я уже нашел здесь. E>Просуммировать то, что там написано можно так: E>- свободные функции и статические методы -- это R function(A); E>- методы объектов и вложенные функции -- это R delegate(A).
Просуммировать это можно так. В D нет функциональных типов, а есть ссылка на функцию и то, что считается продвинутым аналогом указателя на член класса. Функции и "ссылки" на них делятся на два сорта, что не может не сказаться отрицательно на универсальности аналогов hof. Упрощенно говоря, задачи, которые решаются в функциональном языке первоклассными функциями, в D решаются с помощью четырех различных сущностей. C'est charmant!
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, eao197, Вы писали:
E>>>Если вы пропустите скомпилированный код через jad, то увидите, что конструкции f.getClass и foo.getClass применяются не к функциям, а к специальным объектам, которые Nice создает для хранения ссылок на эти функции. K>>Вообще-то это детали реализации. E>Это было бы деталями реализации, если бы у Nice была спецификация языка и несколько независимых реализаций компиляторов.
Детали реализации, на мой взгляд, — это детали реализации вне зависимости от того, существует одна реализация, две, или вообще ни одной.
Если это не деталь реализации, то это деталь чего, позвольте спросить?
E>А в данном случае это всего лишь демонстрация того, что при необходимости представления ссылки на функцию Nice прибегает к тем же средствам, что и Eiffel -- конструированию объекта, содержащего ссылку на функцию/метод.
Вот только в Eiffel это явно прописывается в коде, а в Nice на уровне языка никак не проявляется.
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
K>class A {
K> int inc(int a ) = a + 1;
K>}
K>int inc(int a) = a + 1;
K>void main( String[] args ) {
K> let o = new A();
K> let i = o.inc(1);
K> (A, int)->int f = inc;
K> let j = f(o, 1);
K> println(i == j);
K>}
K>
Это частный случай, когда можно сделать различие по типам аргументов. Представте, например, что есть:
// Первый файл.package p1;
void serialize( String s, long l ) { ... }
// Второй файл.package p2;
void serialize( String s, long l ) { ... }
// Третий файл.import p1;
import p2;
void main( String[] args ) {
(String, long)->void f = serialize;
}
Полное имя p1.serialize компилятор nice не считает валидным выражением.
E>>Ну я не знаю, как, в принципе, (int)->int может быть тем же самым, что и (A, int)->int. K>
K>И почему, внутри класса A метод inc имеет сигнатуру (int)->int, а вне -- (A,int)->int? Это, вообще-то говоря, разные функции.
K>Еще раз. Метод имеет сигнатуру (A,int)->int. Внутри он, снаружи — это не важно. просто первый аргумент может в некоторых случаях быть неявным.
Да, это я ошибся.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, eao197, Вы писали:
E>>>>Если вы пропустите скомпилированный код через jad, то увидите, что конструкции f.getClass и foo.getClass применяются не к функциям, а к специальным объектам, которые Nice создает для хранения ссылок на эти функции. K>>>Вообще-то это детали реализации. E>>Это было бы деталями реализации, если бы у Nice была спецификация языка и несколько независимых реализаций компиляторов.
K>Детали реализации, на мой взгляд, — это детали реализации вне зависимости от того, существует одна реализация, две, или вообще ни одной.
Если вообще нет ни одной реализации, то речь не может идти о языке программирования. Максимум -- о проекте языка.
K>Если это не деталь реализации, то это деталь чего, позвольте спросить?
Реализации, реализации. Только вот эта деталь показывает, что функции в Nice не копируются. И функциональные типы в действительности являются ссылками на функции. Это такая деталь, которую хорошо бы понимать при использовании языка.
E>>А в данном случае это всего лишь демонстрация того, что при необходимости представления ссылки на функцию Nice прибегает к тем же средствам, что и Eiffel -- конструированию объекта, содержащего ссылку на функцию/метод.
K>Вот только в Eiffel это явно прописывается в коде, а в Nice на уровне языка никак не проявляется.
Программист от этого вряд ли сильно страдает, ведь в Eiffel он все равно может делать то же самое, что и в Nice.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, eao197, Вы писали:
E>>Вот как работают ссылочные типы в D: E>>
E>>class Demo { ... }
E>>void f( Demo d ) {
E>> // d -- это ссылка на экземпляр Demo.
E>>}
E>>void g() {
E>> Demo o = new Demo; // o -- это ссылка на экземпляр Demo.
E>> f( o ); // Передача по ссылке.
E>>}
E>>
K>Странно. Если функцию все равно можно передать только по ссылке, зачем это указывать явным образом? Ситуация с объектами гораздо логичнее.
Что явным образом указывать? Ссылка на функцию -- это делегат. Делегат передается либо по значению, либо по указателю. Объекты тут причем? Объекты используются в Eiffel и Nice.
K>>>Я уже нашел здесь. E>>Просуммировать то, что там написано можно так: E>>- свободные функции и статические методы -- это R function(A); E>>- методы объектов и вложенные функции -- это R delegate(A).
K>Просуммировать это можно так. В D нет функциональных типов, а есть ссылка на функцию и то, что считается продвинутым аналогом указателя на член класса. Функции и "ссылки" на них делятся на два сорта, что не может не сказаться отрицательно на универсальности аналогов hof.
С чего бы это? Когда в Nice нужно привести (A, int)->int к (int)->int вас не смущает использовать карринг. А в D выразить int function(int) через int delegate(int) как два байта переслать, и это орицательно сказывается?
K>Упрощенно говоря, задачи, которые решаются в функциональном языке первоклассными функциями, в D решаются с помощью четырех различных сущностей.
Четыре откуда?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
K>>Детали реализации, на мой взгляд, — это детали реализации вне зависимости от того, существует одна реализация, две, или вообще ни одной. E>Если вообще нет ни одной реализации, то речь не может идти о языке программирования. Максимум -- о проекте языка.
C моей точки зрения, которая, насколько я знаю, не слишком отличается от общепринятой, язык программирования — это набор синтаксических и семантических правил. Наличие компилятора не обязательно.
E>Только вот эта деталь показывает, что функции в Nice не копируются.
А это, как раз, не деталь реализации. Это семантика функциональных типов. Они в Nice — ссылочные.
E>И функциональные типы в действительности являются ссылками на функции.
Нет. Функция в Nice — экземпляр ссылочного функционального типа. А ссылку на экземпляр функционального типа содержит переменная.
E>Это такая деталь, которую хорошо бы понимать при использовании языка.
Естественно.
E>>>А в данном случае это всего лишь демонстрация того, что при необходимости представления ссылки на функцию Nice прибегает к тем же средствам, что и Eiffel -- конструированию объекта, содержащего ссылку на функцию/метод. K>>Вот только в Eiffel это явно прописывается в коде, а в Nice на уровне языка никак не проявляется. E>Программист от этого вряд ли сильно страдает, ведь в Eiffel он все равно может делать то же самое, что и в Nice.
Еще раз. Мы говорим не о каких-то гипотетических страданиях программистов на Eiffel, стонущих под гнетом отсутствия первоклассных функций в этом языке. Мы решаем проблему классификации и демаркации. Я неоднократно говорил о том, что с практической точки зрения разница малозначительна.
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, eao197, Вы писали:
K>>Странно. Если функцию все равно можно передать только по ссылке, зачем это указывать явным образом? Ситуация с объектами гораздо логичнее. E>Что явным образом указывать?
Явно указывать взятие ссылки на функцию.
E>Объекты тут причем?
Объекты при том, что для их передачи не нужно явным образом брать ссылку. Они просто имеют семантику ссылочного типа — вот и все.
K>>Просуммировать это можно так. В D нет функциональных типов, а есть ссылка на функцию и то, что считается продвинутым аналогом указателя на член класса. Функции и "ссылки" на них делятся на два сорта, что не может не сказаться отрицательно на универсальности аналогов hof. E>С чего бы это? Когда в Nice нужно привести (A, int)->int к (int)->int вас не смущает использовать карринг. А в D выразить int function(int) через int delegate(int) как два байта переслать, и это орицательно сказывается?
Меня не смущает использование карринга для того, чтобы из функции типа A * int -> int сделать функцию типа int -> int. Но вот два несовместимых типа int -> int и int -> int меня несколько напрягают. На том же C# можно написать сколько угодно несовместимых типов int -> int, вот только функция типа int -> int будет подходить к любому из них.
K>>Упрощенно говоря, задачи, которые решаются в функциональном языке первоклассными функциями, в D решаются с помощью четырех различных сущностей. E>Четыре откуда?
Два сорта функций и два сорта делегатов. Итого — четыре. То, что функция и подходящий ей делегат — разные сущности я уже продемонстрировал примером на псевдо-D выше.
... << RSDN@Home 1.2.0 alpha rev. 774>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Здравствуйте, Klapaucius, Вы писали:
K>>>Странно. Если функцию все равно можно передать только по ссылке, зачем это указывать явным образом? Ситуация с объектами гораздо логичнее. E>>Что явным образом указывать?
K>Явно указывать взятие ссылки на функцию.
E>>Объекты тут причем?
K>Объекты при том, что для их передачи не нужно явным образом брать ссылку. Они просто имеют семантику ссылочного типа — вот и все.
Кстати, с этой стороны тоже надо посмотреть на вопрос.
eao197, Klapaucius, если взять язык типа C#, но без struct. Т.е. все пользовательские объекты будут иметь ссылочную семантику. Вопрос: объекты будут первоклассными сущностями? Передать их в функцию нельзя (только ссылку), вернуть нельзя (только ссылку), но можно создавать и удалять.
Теперь возьмем работу с функцией как в C++, т.е. не обязательно указывать &foo, можно просто foo, и для вызова аналогично. Понятно, что это сахар, да еще, ЕМНИП, не стандартный, хотя тут не копался, не столь важный вопрос. Но все же — функции в данном случае первоклассны или нет?
Если объекты в приведенном псевдо-C# не первоклассны, то вопросов нет.
Если объекты первоклассны, а функции в Си++ — нет, тогда почему? Что еще нужно, создание и удаление?
Хотелось бы услышать мнение обоих, спасибо
Свое четкое мнение сформировать не могу из-за неких противоречий. С одной стороны — если объекты в некоем языке только и умеют, что по ссылке передаваться, и "круче" объектов ничего больше нет (т.е. с бОльшими возможностями), то надо считать их для этого языка первоклассными и предъявлять те же требования для функций. Но тогда по логике, императивный язык с передачей параметров по значению может быть функциональным только тогда, когда функцию можно будет копировать и изменять, даже по ссылке, т.е.
void foo (int -> int & fun_ref)
{
fun_ref << (x){ assert(x > 0); } // добавили новый код в начало - проверка параметра
}
int my (int x) { return x - 10; } // объявили новую функциюvoid test()
{
foo (my); // изменили ее
my (-10); // ошибка!
}
Можно, правда, считать, что стандартное объявление — это именно определение константной функции, т.е.
int const x = 5;
int my_x (int x) { return x - 10; } // константная функцияint y = 6; // мутабельный объектint -> int my_y = (x){return x - 10;} // мутабельная функция
Т.е. my_x — аналогично char const * c = "dsfsdf" которое может расположиться в read-only памяти и менять которое никак нельзя. А для того, чтобы быть функциональным, языку необходимо поддерживать именно копирование, создание, передачу по ссылке и все все, что имеется для объектов.
Т.е. варианта два: или наделять функции этими возможностями, или отнимать их у объектов. Например, убрать мутабельность