All streams
Search
Write a publication
Pull to refresh
33
0
Oleg Butko @deviator

Программист

Send message
я постараюсь на эти вопросы ответить в следующей статье)
Если Вы хотите передать структуру/класс в другой поток она должна быть либо shared, либо immutable. Соответственно вызоваемые методов либо должны быть константными и чистыми, либо Вы должны обозначить их как shared (и прописать необходимые синхронизации в случае структур) или immutable. Такая система типов по началу может вызывать определённый дискомфорт, но если к ней пригледеться, то многое становится ясным.
Ошибаетесь. Просто накладывает соответствующие ограничения. Если Вы хотите просто передавать экземпляр какой-то своей структуры между потоками, то просто все методы доступа должны быть pure const, а методы изменения по определению не могут вызываться для immutable объекта. В следующей статье будет больше подробностей.
Как я уже писал на оффсайте ведётся обсуждение и есть решение. Проблема больше идеологическая, существует 2 подхода:
  • реализовать неявную шаблонизацию (с возможностью перегрузки)
  • либо оставить только функцию принимающую ref, а вызов реализовать через временную переменную
    func(5);
    // разворачивается в
    {
        auto __tmp_var__ = 5;
        func( __tmp_var__ );
    }
    

очень классно было бы, если бы Вы попробовали научить кого-нибудь из младших братьев/сестёр (не своих, так друзей) и предоставили бы результаты «исследования»: в каких моментах именно go дети чаще ошибаются, что даётся сложнее/проще и тд
а так получается агитация и мало доказательств
ну это совсем не комильфо… всё вроде строго, а тут БАЦ! и разные типы в контейнер помещаются…
если в контексте обучения программированию, то это как-то сбить с толку может и выстроить в голове не правильные логические последовательности и паттерны мышления (контейнер -> нужно проверять тип элемента), которые в других языках будут не всегда работать (проверка типа такая нужно только ЯП с дин. типизацией, о которой Вы в контексте обучения отзываетесь не лестно). но это конечно имхо
сколько ещё неоднородностей подобных язык таит в себе сей?
Может лучше всё же не переводить, а адаптировать интересную информацию под пользователей хабра?
Насчёт выделения памяти библиотеками. Насколько я понял, сейчас подготовлены аллокаторы для предоставления выбора способа выделения памяти? Или логический смысл этой библиотеки другой?
Прошу прощения! Вы правы, demangling в gdb действительно есть, но он не полный. Для проверки взял старый проект, чуть-чуть поправил, чтобы он упал в нужном месте и вот такой стек получил:
#0  0x000000000084b20f in draw.TestScene.prepareAbstractModel() (this=0x7ffff45cc300) at src/draw.d:56
#1  0x000000000084b06c in draw.TestScene.this(des.space.camera.Camera) (this=0x7ffff45cc300, cam=0x7ffff45cc158) at src/draw.d:39
#2  0x000000000080aa85 in _D3des4util4arch3emm21ExternalMemoryManager57__T6newEMMTC4draw9TestSceneTC6camera18MouseControlCameraZ6newEMMMFC6camera18MouseControlCameraZC4draw9TestScene (
    this=0x7ffff45cc238, _param_0=0x7ffff45cc100) at descore/import/des/util/arch/emm.d:49
#3  0x000000000084fa8c in window.MainWindow.prepare() (this=0x7ffff45cc200) at src/window.d:26
#4  0x000000000069ea60 in des.app.base.DesApp.addWindow(des.app.base.DesWindow() delegate) (this=0x7ffff45cd780, winFunc=...) at des/import/des/app/base.d:318
#5  0x000000000084f808 in D main () at src/main.d:11

Не деманглится имя шаблонной функции (фрейм 2), в остальном всё, кажется, в порядке. Возможно из-за того, что очень часто пользуюсь шаблонами и не заметил, что в остальных случаях всё работает.
Для шаблонных функций не стоит указывать, чтобы сделать их более гибкими в использовании, необходимые атрибуты могут вычислиться компилятором в зависимости от контекта вызова (инстанцирования) функции. Для обычных функций нужно указывать.
Пример
import std.stdio;
import std.typetuple;
import std.range;

template isIRWL(R) { enum isIRWL = isInputRange!R && hasLength!R; }
template FloatHandler(R) { enum FloatHandler = is( ElementType!R == float ); }

float avg(R1,R2)( R1 a, R2 b ) // не указываем какая функция
    if( allSatisfy!(isIRWL,R1,R2) && allSatisfy!(FloatHandler,R1,R2) )
{
    auto c = chain( a, b );
    float res = 0.0f;
    foreach( val; c ) res += val;
    return res / c.length;
}

struct Bar
{
    float val;
    size_t cnt;

@nogc: // все функции в этой структуре такие
    this( float n, size_t c ) { val = n; cnt = c; }
    void popFront() { cnt--; }
    float front() { return val; }
    size_t length() @property { return cnt; }
    bool empty() { return cnt == 0; }
}

float call_nogc() @nogc // указываем конкретно
{
    // всё в порядке, avg инстанцируется как @nogc,
    // так как все вызовы в Bar @nogc
    return avg( Bar(1.0f,3), Bar(4.0f,6) );
}

struct Foo
{
    float val;
    size_t cnt;

    // здесь вызовы обычные
    this( float n, size_t c ) { val = n; cnt = c; }
    void popFront() { cnt--; }
    float front() { return val; }
    size_t length() @property { return cnt; }
    bool empty() { return cnt == 0; }
}

// код с ошибочным вызовом
//float foo_call_nogc() @nogc // функция помечена как @nogc
//{
//    return avg( Foo(1,10), Foo(8,2) );
//
//    пытается вызвать non-@nogc функции в Bar
//    attrib.d(54): Error: @nogc function 'attrib.foo_call_nogc' cannot call non-@nogc function 'attrib.Foo.this'
//    attrib.d(54): Error: @nogc function 'attrib.foo_call_nogc' cannot call non-@nogc function 'attrib.Foo.this'
//    avg инстанцируется соответствующим образом, как non-@nogc
//    attrib.d(54): Error: @nogc function 'attrib.foo_call_nogc' cannot call non-@nogc function 'attrib.avg!(Foo, Foo).avg'
//}

float foo_call()
{
    return avg( Foo(1,10), Foo(8,2) ); // тут всё в порядке, мы повторно используем avg
}

void main()
{
    writeln( call_nogc() );
    writeln( foo_call() );
}

как и gdb — никак)
Трансляция python в D это кажется вот это.
Не совсем понимаю зачем это может быть нужно, имхо смысл python встраивать в D в том, что python динамичный, его не надо компилировать, его можно использовать как конфиг программы, изменять на лету и тд, то есть по настоящему скриптовой язык. А так получается ни рыба ни мясо.
Насчёт фундаментальности я говорил в плане исправления. Ошибка при запуске программы была вида 'already defined', и относилась к загрузке дин. библиотеки phobos. Но видимо я несколько ошибся насчёт простоты её исправления. Не совсем понял насчёт виртуальной машины. pyd не является самостоятельной виртуальной машиной, используется cpython, может я не совсем понял о чём Вы? И что означает термин full-resumable?
Как минимум пакетный менеджер языка dub, хотя этим врятли можно удивить. При увеличении популярности будут и программы.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity