Мысли о пользовательских прилагательных в С++
От: Went  
Дата: 05.12.16 10:18
Оценка:
Здравствуйте. Знаю, подобные темы мало кому тут интересны, но так долго с ней ношусь, что нужно ее записать, иначе не успокоюсь

С++ в чем-то копирует естественные языки. У него есть грамматика, пунктуация, морфология и т.п. У него есть существительные (собственные — имена объектов, нарицательные — имена типов), глаголы (функции), предлоги (некоторые ключевые слова). У него есть и прилагательные (const, mutable, volatile, register, virtual). Так сложилось, что все прилагательные (в отличие от существительных и глаголов) — жестко вшиты в язык и расширению не поддаются. В результате, вместо простого пользовательского прилагательного нам приходится использовать громоздкие и слишком конкретные структуры в виде связки двух существительных: вместо "синий дом", мы пишем "некий синий объект, который похож на дом".
something_blue<house> my_house;

вместо
blue house my_house;

Вроде бы ничего страшного, привычный вариант кажется понятным и читаемым, но почему тогда вместо
const int number;

мы не пишем
const<int> number;

Помню, кто-то даже предлагал объявить старую нотацию устаревшей и использовать шаблонно-подобную везде, в том числе и для указателей. Моя же идея заключается в том, чтобы, напротив, дать возможность программисту самому определять эти прилагательные:
class some_class : public base_class
{
  shared *int    counter;
  atomic  float  real;
  
  radian float angle;
};

Понятно, что shared *int развернется в shared_ptr<int>, atomic float в atomic<float> и т.п. То есть программист где-то выше пишет:
template<typename T>
declspec shared<T*> = shared_ptr<T>; // Можно любое слово ключевое придумать, не суть важно.

и компилятор будет подставлять шаблон вместо "прилагательного".

"Зачем весь этот цирк?", спросите вы. Дело не только и не сколько в синтаксическом сахаре, сколько в том, что явное определение шаблона слишком конкретно, оно не дает возможности "спрятать" от пользователя то, чем на самом деле окажется результат подстановки, абстрагироваться от конкретного типа объекта. Ведь прилагательное может применяться не только к определению переменной, и не просто подменять тип.

1. Оно может декорировать тип:
// Фактически, сильный тайпдеф с возможностью приведения
template<typename T>
declspec radian<T> = T;
template<typename T>
declspec degrees<T> = T;

// Но можно перегрузить функцию
template<typename T>
degrees T& operator = (degrees T& d, const radian T& r)
{
  d = (T)r * 180.0 / 3.1415
  return d;
}

// И использовать как для float, так для double.
radian float angle = 3.1415f;
degrees float other = angle; // (float)other = 180.0f


2. Может подменить функцию:
// Возможный синтаксис декларации опущу, просто пример использования:
class some_class
{
  int do_some_really_hard(int n) asyncfn
  {
    return some_hard_computing(n) * some_other_hard_computing(n);
  }
};
// Раскроется в
class some_class
{
  // Видимо для пользователя
  future<int> do_some_really_hard(int n)
  {
    return async(std::launch::async, [=](){return __do_some_really_hard(n);})
  }

  // Невидимо для пользователя
  int __do_some_really_hard(int n)
  {
    return some_hard_computing(n) * some_other_hard_computing(n);
  }
};


3. Может подменить определение класса:
// Класс, который пишется в фабрику по имени типа
dynamic class B : public A
{
  virtual void do();
};

Раскроется в
class __B : public A
{
  virtual void do();
};
class B : public __B
{
  virtual string get_real_type();

private:
  static auto __class_registrator = register_class<B>();
};


И тому подобное. Одна декларация сможет определить сразу несколько типов или переменных, обратиться к this, если декларация внутри класса, быть переопределена для разных аргументов. Понятно, что подобные "прилагательные" будут подобно типам и переменным привязаны к пространствам имен, а не будут глобальными подобно встроенным. Тему можно развивать, но мысль, я думаю, ясна. Критикуйте, если в этом есть какой-то смысл
Отредактировано 05.12.2016 10:23 Went . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.