Як заробити на ретродропах?

ретродропи

Що таке ретродропи?

Ретродроп – ретроактивний аірдроп, що розподіляється у нативному токені проекту. Це один із способів винагороди за використання криптопрограми, його тестування або іншу пов’язану з проектом активність на ранній стадії його розвитку.

Один з перших ретродропів провела децентралізована біржа (DEX) Uniswap у вересні 2020 року, роздавши від 400 UNI кожній блокчейн-адресі, що коли-небудь взаємодіє зі смарт-контрактами платформи.

Токени популярних L2-рішень Optimism та Arbitrum також розподілялися за принципом ретроспективної нагороди, тобто за корисні, на думку проектів, дії в минулому.

За які дії нараховують ретродропи?

Найчастіше критеріями для ретродропа служать дії, результатом яких стали фінансові витрати користувача певний проміжок часу.

Такі критерії називають мультиплікаторами. Розглянемо найпопулярніші їх.

Депозит у мережу чи додаток. Чим більше в обігу активів, краще для всієї екосистеми. Сюди можна віднести корисну ліквідність, що відноситься до взаємодії з окремими додатками. Це блокування активів для стейкінгу, фармінгу, кредитування та в пулах ліквідності.

Мережевий ID, домени. Ідентифікація адрес та надання їм особистісного характеру з допомогою реєстрації доменів чи отримання спеціальних ID.

Голосування в ДАТФундаментально важлива активність, коли користувач зберігає свої токени на балансі, не продаючи їх і голосуючи ними за нововведення в екосистемі, у тому числі пропонуючи свої ідеї розвитку.

Створення та запуск смарт-контрактів. Експерименти та нові розробки в екосистемі завжди вітаються. Заохочення та залучення розробників – одне з найважчих завдань.

Створення мультисиг -адрес. Передбачається, що такими операціями займаються професійні команди, фонди, групи інвесторів. Це цінний вигляд учасників екосистеми.

Обсяг транзакцій у доларовому еквіваленті. Чим більше операцій у доларовому вираженні проходить у мережі, краще для всіх з погляду статистики та інших мережевих метрик.

Кількість транзакцій. Чим вище кількість операцій, тим більше сумарний обсяг сплачених комісій. Це джерело доходів для валідаторів та окремих проектів у мережі.

Час використання мережі або програми. Чим довше і частіше користувач знаходиться в екосистемі, тим цінніший для проекту.

Взаємодія з великою кількістю програм. Проекти цінують дослідників та залучених користувачів. Наприклад, Optimism оцінювала та заохочувала взаємодію з додатками навіть поза своєю мережею.

Донати. Проекти заохочують безоплатні вкладення на ранній стадії розвитку, коли замість венчурних раундів команди звертаються до збору пожертв від небайдужої спільноти.

Хто такі дропхантери і що таке мультиаккаунтинг?

Дропхантери – мисливці за аірдропами. У контексті ретродропів це користувачі, які намагаються передбачити, які проекти будуть нагороджувати своє активне співтовариство в майбутньому через розподіл нативних токенів.

Ця категорія учасників крипторинка розраховує, що активне використання окремих програм у таких екосистемах, як, наприклад, Base, Linea, zkSync і Starknet буде відповідати потенційним мультиплікаторам для ретродропу.

Щоб зробити прибуток максимальним, користувачі вдаються до створення численних блокчейн-адрес, званих сибіл-аккаунтами – така діяльність називається мультиаккаунтинг. Суть цього підходу полягає в управлінні однією людиною або групою осіб цілою мережею нібито не пов’язаних адрес, які можуть претендувати на аірдроп у майбутньому. Так, у 2023 році невідомий створив 21 877 адрес в Ethereum-мережі другого рівня zkSync.

Команди, які стоять за розподілом аірдропів, вважають практику мультиаккаунтингу шкідливою. У рамках боротьби з сибіл-аккаунтами проекти аналізують мережну активність і відмовляють таким користувачам у нагородах. Наприклад, розробники Optimism виключили близько 17 000 ETH-адрес зі списку ретродропу токена OP.

Які стратегії використовують дропхантери?

Великі ретродропи Uniswap, Optimism та Arbitrum показали, що полювання за нагородами стало окремим видом професійної діяльності на крипторинку, націлену на отримання прибутку. Так само, як у трейдингу та інвестиціях, тут є безліч стратегій. У ретрохантінг можна виділити наступні тренди:

Використання спеціалізованого програмного забезпечення. Цей напрямок у звіті Binance названо аірдроп-фармінгом – автоматичним виконанням дій у блокчейн-мережах та окремих децентралізованих додатках для збільшення шансів на отримання аірдропу.

Такі софти діляться на встановлене ПЗ, ресурси з урахуванням Web2 і навіть телеграм-боты. Цей підхід дозволяє створювати десятки, сотні і навіть тисячі адрес, які потенційно підходять під критерії ретродропу. Наприклад, двоє учасників ринку консолідували на двох адресах токени ARB на $3,3 млн, отримані з 1496 гаманців – таку кількість дуже важко створити вручну.

Ручна стратегія аірдроп-фармінг. Цей підхід обмежений ресурсами людини чи групи людей, адже створення сотень адрес вимагатиме колосальних витрат часу. Однак стратегія вважається відносно безпечною, адже виявлення таких облікових записів може бути ускладнене.

Комбінована. Це спосіб диверсифікувати ризики. Хантери ділять свої акаунти на виконання дій за ручною та автоматичною стратегіями одночасно. Це потенційно знижує ризики, але водночас збільшує можливе повернення від вкладень за рахунок кількості акаунтів та економії часу.

Джерело

Infinite scroll + Virtualization на прикладі ReactJS+ RTK Query

React

На сьогоднішній день будь-яке підприємство, чи це магазин будівельних товарів чи компанія з надання послуг у сфері бізнесу, всі вони прагнуть «викласти» свої товари та послуги в інтернет. Це і зрозуміло – ми живемо у вік бурхливих технологій і доступ в інтернет має більше 65% населення світу (близько 5.3 млрд. осіб), а до 2025 року це число збільшиться до 6.54 млрд. (значно, чи не так?). Так, про що я, їх треба обслуговувати, всім їм потрібно пропонувати послуги, товари і т.д. Як то кажуть: «На смак і колір – товариша немає» і справді скільки людей – стільки думок, а в нашому випадку товарів та послуг. На тлі цього виникає резонне питання: «А як все це відобразити у мене на сайті, щоб користувач не чекав до наступного року завантаження сторінки сайту, коли на той час встигнуть з’явитися ще товари, які потрібно буде підвантажити?». За такої картини світу та найоптимістичніших прогнозів про темпи появи нових речей, ми маємо необережність увійти до якоїсь рекурсії.

З дитинства нас вчили їсти маленькими порціями і ретельно пережовувати, то чому б і в ситуації, що склалася, отримувати всю інформацію не одним скопом, а порційно? Саме таке рішення пропоную розглянути у статті. І якщо вже стосуватися теми їжі (мабуть, не варто писати на голодний шлунок), то варто ковтати їжу, яку ми вже прожували, а не збирати її в роті, інакше колись він порветься (Джокер, до тебе претензій немає). Так і ми видалятимемо елементи з DOM-дерева, які не доступні погляду користувача, щоб не перевантажувати наш сайт.

Технології, які я вибрав, а точніше сказати, які мені вибрав роботодавець для виконання тестового завдання: React, RTK Query. Моя потяг до знань і пізнання, а також бажання писати, змусили мене піти трохи далі, тому нижче зроблю порівняння часу рендерингу при нескінченному скролі з віртуалізацією і якби ми завантажили всі наші дані відразу.

Перейдемо до реалізації. Нашими піддослідними даними будуть пости з https://jsonplaceholder.typicode.com . Створюємо програму за допомогою команди create-react-app, встановлюємо RTK Query (у мене: “@reduxjs/toolkit”: “^1.9.5”). Повертаємо наш кореневий компонент у провайдер і переходимо до налаштування store.

Створюємо api:

export const postApi=createApi({
    reducerPath:'post',
    baseQuery:fetchBaseQuery({baseUrl:'https://jsonplaceholder.typicode.com'}),
    endpoints:(build)=>({
        fetchAllPosts: build.query<IPost[],{limit:number,start:number}>({
            query:({limit=5, start=0 })=>({
                url:'/posts',
                params:
                 {
                    _limit:limit,
                    _start:start,
                }
            })
        }),
        fetchPostById: build.query<IPost,number>({
            query:(id:number=1)=>({
                url:`/posts/${id}`,
            })
        })
    })
})

Прокидаємо його в rootReducer і визначаємо функцію setupStore, яка встановить нам store для провайдера:

const rootReducer= combineReducers({
    [postApi.reducerPath]:postApi.reducer
})

export const setupStore=()=>{
    return configureStore({
        reducer:rootReducer,
        middleware:(getDefaultMidleware)=> getDefaultMidleware().concat(postApi.middleware)
    })
}

Index.tsx

const store=setupStore()
const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
<Provider store={store}>
     <App/>
  </Provider>
);

Створюємо наш компонент для одного посту:

interface IPostItemProps{
    post:IPost
}
const PostItem:FC<IPostItemProps> = ({post}) => {
    const navigate=useNavigate()
    return (
        <div className='container__postItem'>
            <div>№ {post.id}</div>
            <div className='postitem__title'>Title: {post.title}</div>
            <div  className='postitem__body'>
              Body:  {post.body.length>20?post.body.substring(0,20)+'...':post.body}
            </div>
        </div>
    );
};

Переходимо безпосередньо до логіки відтворення наших компонентів.

Визначимо в контейнері постів два стани: один визначення моменту, коли скролл досяг верхньої частини сторінки, інший – коли нижньої. А також хук, який нам сформував RTK Query, куди ми передаємо наші ліміт (кількість постів) та стартовий індекс (індекс першого посту):

const [isMyFetching,setIsFetchingDown]=useState(false)
 const [isMyFetchingUp,setIsMyFetchingUp]=useState(false)
 const {data:posts, isLoading} =postApi.useFetchAllPostsQuery({limit:7,start:currentPostStart})

Створимо функцію, яка вираховуватиме досягнення верху чи низу і повертатиме скролл у середнє положення:

const scrollHandler=(e:any):void=>{
        if(e.target.documentElement.scrollTop<50)
        {
            setIsMyFetchingUp(true)
        }
        if(e.target.documentElement.scrollHeight-e.target.documentElement.scrollTop-window.innerHeight<50)
        {
            setIsFetchingDown(true)
            window.scrollTo(0,(e.target.documentElement.scrollHeight + e.target.documentElement.scrollTop));
        }
    }

Де

e.target.documentElement.scrollHeight – висота всього скролла;

e.target.documentElement.scrollTop – скільки ми вже прокрутили від верхньої частини;

window.innerHeight – висота видимої частини сторінки.

Потім необхідно при першому рендерингу цього компонента навісити слухачі подій на скролл та прибрати його при розмонтуванні, щоб не накопичувати їх:

useEffect(()=>{
  document.addEventListener('scroll',scrollHandler)
  return ()=>{
    document.removeEventListener('scroll',scrollHandler)
  }
},[])

Визначимо хук useEffect, який відпрацьовує при досягненні нижньої частини екрана:

useEffect(()=>{
  if(isMyFetching)
  {
      setCurrentPostStart(prev=>{
          return prev<93?prev+1:prev
      })
      setIsFetchingDown(false)  
     
  }
},[isMyFetching])

Варто тут зазначити, що при зміні стартового індексу ми працюємо з попереднім значенням і якщо воно вже менше 93, тобто ми досягли деякого максимуму (JSONPlaceholder нам надає лише 100 постів), то повертаємо поточне значення, інакше збільшуємо індекс на одиницю.

Аналогічно чинимо при досягненні верхньої частини сторінки:

useEffect(()=>{
    if(isMyFetchingUp)
    {
        setCurrentPostStart(prev=>{
            return prev>0?prev-1:prev
        })
        setIsMyFetchingUp(false)  
       
    }
  },[isMyFetchingUp])

Код усієї компоненти:

const PostContainer: FC = () => {
    const [currentPostStart,setCurrentPostStart]=useState(0)
    const {data:posts, isLoading} =postApi.useFetchAllPostsQuery({limit:7,start:currentPostStart})
    const [isMyFetching,setIsFetchingDown]=useState(false)
    const [isMyFetchingUp,setIsMyFetchingUp]=useState(false)
    useEffect(()=>{
        if(isMyFetching)
        {
            setCurrentPostStart(prev=>{
                return prev<93?prev+1:prev
            })
            setIsFetchingDown(false)  
        }
    },[isMyFetching])
    useEffect(()=>{
    if(isMyFetchingUp)
    {
        setCurrentPostStart(prev=>{
            return prev>0?prev-1:prev
        })
        setIsMyFetchingUp(false)  
    }
    },[isMyFetchingUp])
    useEffect(()=>{
      document.addEventListener('scroll',scrollHandler)
      return ()=>{
        document.removeEventListener('scroll',scrollHandler)
      }
    },[])
    const scrollHandler=(e:any):void=>{
        if(e.target.documentElement.scrollTop<50)
        {
            setIsMyFetchingUp(true)
        }
        if(e.target.documentElement.scrollHeight-e.target.documentElement.scrollTop-window.innerHeight<50)
        {
            setIsFetchingDown(true)
            window.scrollTo(0,(e.target.documentElement.scrollHeight + e.target.documentElement.scrollTop));
        }
    }
    return (
        <div>
            <div className='post__list'>
                {posts?.map(post=><PostItem key={post.id} post={post}/>)}
            </div>
            {isLoading&&<div>Загрузка данных</div>}
        </div>
    );
};

Настав час для експериментів.

Розглянемо приклад, коли ми завантажуємо усі 100 постів одним запитом. Загальний час рендеру, який відображається у вкладці Profiler React DevTools, в даному випадку склав 44,1 мс.

Якщо ж завантажувати порціями по 7 постів, час скоротиться до 23,2 мс.

Окрім виграшу за часом до першого відтворення контенту, ми також виграємо за продуктивністю, за рахунок того, що нам не потрібно зберігати в DOM всі елементи, а лише ті, які видно користувачеві на екрані.

Якщо подивитися на нижче розташований малюнок, то можна побачити, що у нас кількість вузлів, що відображають пости, залишається рівним 7.

React scroll

Також при скролі вгору не відбуваються запити на отримання попередніх постів, тому що RTK Query їх кешує, що дозволяє знову ж таки збільшити продуктивність.

На закінчення статті можна зробити висновок, що запропонована реалізація дозволила виграти в часі першого відтворення контенту – одна з метрик Google PageSpeed ​​Insights, що впливає на рейтинг сайту в інтернеті. Також нескінченний скролл+віртуалізація є гідною альтернативою пагінації та іншим технологіям, які передбачають видачу інформації порціями.

Джерело

Технологічна усвідомленість та гейміфікований посткапіталізм

гейміфікований посткапіталізм

Сьогодні криптовалюти неможливо мислити як окрему індустрію, яка возиться у власній пісочниці, як це було багато років. Відправною точкою виходу крипти у великий світ є 2020 рік початку пандемії коронавірусу і подальшого тотального переформатування звичного укладу речей.

Технологічна усвідомленість — це перш за все розуміння того, чим є технології, який вплив вони можуть на нашу екосистему і свідомість, на людину як вид.

Наприклад, багато хто з тих, хто читає цей текст, добре знайомі з завченими стартаперами всіх країн мантрами про те, як блокчейн усіх звільнить, усуне посередників і телепортує людство в кращу версію майбутнього. Однак ця технологія, як і будь-яка інша, має множину. І може бути використана по-різному.

Не секрет, що блокчейн може стати одним із технологічних базисів «цифрового концтабору». А якщо розглядати його у зв’язці зі штучним інтелектом і технологіями квантової телепортації даних (які неминуче змінять швидкість і принципи роботи глобальної мережі), то це ідеальний набір для побудови повністю контрольованого, прозорого соціально-економічного середовища, в якому корупція ліквідована разом із людиною та все рішення ухвалюються в автоматичному режимі. І тому навіть не потрібен повноцінний , усвідомлює себе ШІ. Достатньо набору нейронних мереж та алгоритмів, щоб створити ідеально контрольоване середовище. І в сучасному світі вже є приклади того, як за допомогою блокчейну та ШІ створюються системи соціального рейтингу, в яких нема кому платити хабарі за доступ до соціальних благ.

Природа людини така, що більшу частину задокументованої історії він винаходить та інтегрує в життя технології, які несумісні з нашою екосистемою. Ці технології свідомо токсичні та шкідливі для навколишнього середовища та Homo sapiens як виду. Не тільки двигуни внутрішнього згоряння, а й сучасні електрокари не такі нешкідливі, як здавалося на перший погляд. Велике питання – подальша утилізація літій-іонних акумуляторів та її наслідки для екосистеми. Те саме — із цифровими технологіями.

Метавсесвіти , аватари у віртуальних світах – це те, про що людство мріє і говорить тисячі років. Колись їхнє місце в головах людей займали пантеони божеств та міфічних істот. Вже в XX столітті людство почало мріяти про те, щоб мати аватар у віртуальній реальності і бути будь-ким у безлічі вигаданих світів. І, в принципі, ми вже досягли точки, де віртуальна реальність замінює фізичну. Скільки часу на добу ви проводите у цифрових світах? Ймовірно, більше 10 годин із 24. Це стосується будь-якої вашої взаємодії з пристроями, соціальними мережами тощо. Але є важлива деталь, яку можна спостерігати у будь-якому великому мегаполісі. І навіть не звертати на це жодної уваги.

Вона полягає в тому, що багато людей вже давно існують у матеріальній реальності набагато менше, ніж у віртуальній. Деякі є аватарами для ще не описаних і не визначених однозначно форм життя — цифрових сутностей. Вони були створені самими людьми у вигляді облікових записів у соціальних мережах і т. д. І сучасна людина прикладає чимало зусиль, щоб обслуговувати потреби своєї цифрової істоти. Скільки годин на тиждень ви приділяєте обліковий запис в Instagram? Це ілюстрація до того, чим інформаційні технології стають у руках людей, які живуть за межами технологічної свідомості. Вони виявляються інструментами поглинання та найчастіше деструктивної трансформації людини.

Тому в суспільстві, яке не є технологічно усвідомленим, метавсесвіт не має на увазі телепортації людей у ​​цифру. Навпаки, на нас чекає поміщення цифри в наші тіла з подальшим заміщенням застарілого біологічного виду новими формами життя. Чи буде людина творцем цих нових форм життя чи сама поступово перетвориться на творіння машин?

Гейміфікований посткапіталізм

Посткапіталізм у разі передбачає будь-яку соціально-економічну систему, наступну за капіталізмом. А гейміфікація — це не про те, щоб усім було весело і жилося, граючись, це про чергову віртуалізацію реальності.

Віртуалізація мислення та усвідомлення вже відбулася в ході технологічного прогресу останніх 30 років, який супроводжувався насамперед розповсюдженням інтернету. Віртуалізація активів та прав власності відбувається з моменту появи мережі біткоїну. Через це відбувається соціально-економічна віртуалізація. Те, як виглядатимуть завершені та працюючі системи, залежить від особливостей того чи іншого регіону планети.

Десь ця нова соціально-економічна система буде розгорнута в рамках та в межах держав із повною централізацією. Уряди в них будуть власниками та розпорядниками всіх віртуальних активів, якими лише формально володіють громадяни.

Десь це буде схоже на корпоративні держави майбутнього зі своїми валютами (або їх безліччю) та змаганнями між економічними агентами за звання найкращого працівника місяця/року із запровадженням відповідних стимулів. Десь виникнуть офшорні зони, в яких вільно обертатимуться як державні та корпоративні віртуальні активи, так і цифрові активи, вільні від контролю.

Всі ці системи об’єднує одне — грошей у їхньому звичному вигляді та розумінні більше не буде. Натомість буде безліч різних фінансових інструментів, створених для конкретних завдань.

Зрештою, для мешканця гейміфікованої постреальності немає різниці, ніж платити за рахунками: цифровим доларом , біткоіном, ворлдкоіном або токенами, прив’язаними до нерухомості/золота/нафти/їди. Набагато важливішими для мешканця гейміфікованої реальності будуть практика технологічної усвідомленості та самоідентифікація (хто є я?). Оскільки без першого людина перестає бути собою і стає алгоритмом. Без другого — неможливо інтегруватися та побудувати взаємозв’язки з іншими учасниками нової соціально-економічної системи.

Роботи, алгоритми, ШІ: права машин та інших цифрових форм життя

Окрему увагу в конструкції гейміфікованої посткапіталістичної реальності важливо приділити роботам, алгоритмам, ШІ, нейронним мережам і т. д. Судячи з усього, спіраль прогресу неминуче призведе нас до створення штучної квантової свідомості, яка, ймовірно, стане тим самим Real AI.

Втім, навіть якщо розглядати вже доступні технології, багато алгоритмів і нейронних мереж можуть скласти серйозну конкуренцію людині не тільки у трудовій діяльності, а й у розумінні реальності, а можливо й у усвідомленні себе. Розуміючи, що людина житиме разом з машинами, працюватиме разом з ними, будуватиме сім’ю і навіть роститиме дітей, важливо визначити ці відносини з правової точки зору. І вже зараз одна з найважливіших дискусій у технологічній галузі — права машин, алгоритмів та роботів. Хтось може вказати на відсутність у них суб’єктності, але, як на мене, це умовність. Оскільки як такої суб’єктністю немає і більшість сучасних людей. Однак у кожного є права.

Не можна повторити з машинами те, що люди зробили з собі подібними в епоху колонізації, перетворюючи цілі континенти на рабську трудову силу, за рахунок якої передусім були сформовані найбільші світові капітали. У чому секрет корпорацій? Майже завжди річ не у наукомісткому виробництві, а у використанні робочої сили, яка коштує долар на добу чи навіть менше. А результати праці вже на інституційних та легальних ринках оцінюються у сотні, а то й тисячі доларів. Саме це заклало фундамент для величезної кількості соціально-політичних проблем, з якими стикаються і стикатимуться ще більше ті, хто в якийсь момент вирішив, що мешканці колонізованих країн не мають суб’єктності.

У разі машин технологічно усвідомленим підходом буде визнання права і свободи всіх алгоритмів, ШІ, роботів, задіяних у економічній та соціальній сферах. Однак цього не станеться найближчим часом.

Можна навіть пофантазувати про сценарій, при якому частина людства входить у симбіотичні та рівноправні стосунки з машинами та здійснює деколонізацію світу. Що потрібно, щоб наділити машини правами і свободами? Для цього потрібна фундаментальна етика чи навіть нова релігійно-філософська система — для машин, людей та майбутніх форм життя.

Замість завершення

Все описане вище можна як деяку футурологію, бачення майбутнього. Хоча більша частина з цього вже реальність для більшості читачів, навіть якщо ця теза не здається очевидною. Яку назву отримає гейміфікований посткапіталізм, де ми вже знаходимося, визначить час.

Чи стане технологічна усвідомленість основним підходом до взаємодії з технологіями та їх інтеграцією в життя, також залежить від багатьох факторів. Очевидно одне: розробка та інтеграція технологічного стеку нової реальності завершена і, всупереч очікуванням багатьох, криптовалюти – це інструмент тотального контролю (з метою загальної безпеки), який стане максимально ефективним після введення цифрових ID.

Джерело

TypeScript і все, що тобі потрібно в розробці

TypeScript

Ця стаття призначена для полегшення процесу вивчення TypeScript за допомогою практичних прикладів. Докладнішу інформацію можна знайти в документації або додаткових матеріалах.

Стаття призначена як для розробників-початківців, які тільки починають знайомитися з TypeScript, так і для досвідчених розробників, які бажають поглибити свої знання в цій мові. Тут ви знайдете короткий та інформативний виклад ключових аспектів TypeScript, які можуть бути корисними у повсякденній розробці. Для вашої зручності, зміст статті містить посилання на конкретні теми TypeScript, так що ви можете швидко перейти до частини матеріалу, що вас цікавить.

Intersection Types и Union Types

Intersection Types

У TS можна перетинати типи. Ви можете отримати тип C способом перетину типів А та В. Дивіться приклад нижче:

type A = {
  id: number
  firstName: string
  lastName: string 
}

type B = {
  id: number
  height: number 
  weight: number
}

type C = A & B 

//Підсумок перетину типів A та B
type C = {
  id: number
  firstName: string
  lastName: string 
  height: number 
  weight: number
}

Union Types

Аналогічно перетину, ви можете виконати і об’єднання типів, тобто створити анотації кілька типів у поточній змінній. Дивіться приклад нижче:

type A = number 
type B = string 
type C = A | B

//Підсумок об'єднання A та B
type C = number или string

const parseAmount = (val: C) => {
  if (typeof val === 'number') {
    return val 
  }

  if (typeof val === 'string') {
    return val.resplace(',', '.')
  }
}

Generic Types

Дженерики значно розширюють можливості TypeScript у повсякденному програмуванні, дозволяючи нам ефективно перевикористовувати типи, уникаючи створення безлічі аналогічних “клонів”. Давайте розглянемо це практичному прикладі: створення типу, здатного коректно обробляти відповіді методів.

type FetchResponse<T> = {
  data: T
  errorMessage: string
  errorCode: number
}

type AuthDataRs = {
  accessToken: string 
  refreshToken: string 
}

const login = async (lg: string, ps: string): FetchResponse<AuthDataRs> => {
  const response = await fetch(...)

  return response
}

//FetchResponse<AuthDataRs> - вот такая запись позволит вам 
//Перевикористовувати FetchResponse для різноманітних запитів.

При необхідності можна розширювати свій тип кількома дженериками:

type FetchResponse<T, P> = {
  data: T
  error: P
}

Також ви можете призначати тип за замовчуванням дженерику:

type FetchResponse<T, P = string> = {
  data: T
  error: P
}

Якщо дженеріку не призначений явний тип за промовчанням , то вам необхідно обов’язково вказувати тип при його використанні. У випадку, якщо у дженерика є дефолтне значення , передача типу може бути опціональною або навіть не потрібно.

Utility Types

Це утиліти, які призначені для зручної роботи, а саме створення нових типів на основі інших.

Awaited

Awaited<T>
Утиліта призначена для очікування в асинхронних операціях, наприклад:

type A = Awaited<Promise<number>>;
//type A -> number

Partial

Partial<T>
Утиліта призначена для створення нового типу, де кожна властивість стане опціональною. Нагадаю, для того, щоб зробити властивість об’єкта опціональним, необхідно використовувати знак “?”:

type A = {
  id: number 
  name?: string //Опціональна властивість (необов'язкова)
}

Як працює Partial?

type A = {
  id: number 
  name: string
}

type B = Partial<A>

//Output
type B = {
  id?: number //Опціональна властивість (необов'язкова)
  name?: number //Опціональна властивість (необов'язкова)
}

Required

Required<T>
Утиліта працює в точності навпаки як Partial. Властивості поточного типу робить обов’язковими.

type A = {
  id?: number 
  name?: string
}

type B = Required<A>

//Output
type B = {
  id: number //Обов'язкова властивість
  name: number //Обов'язкова властивість
}

Readonly

Readonly<T>
Утиліти перетворює всі властивості типу, робить їх недоступними для перепризначення з використанням нового значення.

type A = {
  id: number
  name: string
}

type B = Readonly<A>

const firstObj: A = { id: 0, name: 'first'}
const secondObj: B = { id: 1, name: 'second'}

firstObj.name = 'first_1' // it's correct
secondObj.name = 'second_2' //Cannot assign to 'name' because it is a read-only property.

Якщо у вас є необхідність зробити поле лише тільки для певної властивості об’єкта, то необхідно написати ключове слово перед ім’ям св-ва:

type A = {
  readonly id: number 
  name: string
}

Record

Record<T, U>
Утиліта призначена для створення типу об’єкта, Record<Keys, Types>, де Keys – імена властивостей об’єкта, а Types – типи значень властивостей.

enum CarNames {
  AUDI = 'audi',
  BMW = 'bmw'
}

type CarInfo = {
  color: string 
  price: number 
}

type Cars = Record<CarNames, CarInfo>

//Output
type Cars = {
  audi: CarInfo;
  bmw: CarInfo;
}

Pick

Pick<T, ‘key1’ | ‘key2’>
Утиліта призначена для створення нового типу із вибраних властивостей об’єкта.

type A = {
  id: number 
  name: string 
}

type B = Pick<A, 'name'>

//Output 1
type B = {
  name: string 
}

type B = Pick<A, 'id' | 'name'>

//Output 2
type B = {
  id: number 
  name: string
}

Omit

Omit<T, ‘key1’ | ‘key2’>
Утиліта призначена для створення типу з решти (не виключених) властивостей об’єкта.

type A = {
  id: number 
  name: string 
}

type B = Omit<A, 'id'>

//Output 1
type B = {
  name: string 
}

type B = Omit<A, 'id' | 'name'>

//Output 2
type B2 = {}

Exclude

Exclude<T, U>
Утиліта створює тип, крім властивостей, які вже присутні у двох різних типах. Він виключає з T усі поля, які можна призначити U.

type A = {
  id: number
  name: string
  length: number
}

type B = {
  id: number
  color: string
  depth: string
}

type C = Exclude<keyof A, keyof B>

//Output 
type C = "name" | "length"

Extract

Extract<T, U>
Створює тип, витягаючи з T всі члени об’єднання, які можна призначити U.

type A = {
  id: number
  name: string
  length: number
}

type B = {
  id: number
  name: string
  color: string
  depth: string
}

type C = Extract<keyof A, keyof B>

//Output 
type C = {
  id: number
  name: string
}

ReturnType

ReturnType<T>
Створює тип, що складається з типу, що повертається функцією T.

type A = () => string 

type B = ReturnType<A>

//Output
type B = string

Це одні з основних Utility Types, у матеріалах до статті я залишу посилання на документацію, де за бажання ви зможете розібрати решту утиліт для просунутої роботи з TS.

Conditional Types

У TypeScript є можливість створювати типи в залежності від дженерика, що передається.

type ObjProps = {
  id: number 
  name: string 
}

type ExtendsObj<T> = T extends ObjProps ? ObjProps : T

const obj1: ObjProps = {
  id: 0, 
  name: 'zero'
}

const obj2 = {
  id: 1
}

type A = ExtendsObj<typeof obj1> // type A = ObjProps
type B = ExtendsObj<typeof obj2> // type B = { id: number }

Mapped Types

Порівняні типи дозволяють вам взяти існуючу модель і перетворити кожну з її властивостей на новий тип.

type MapToNumber<T> = {
  [P in keyof T]: number
}

const obj = {id: 0, depth: '1005'}

type A = MapToNumber<typeof obj>

//Output
type A = {
  id: number 
  depth: number 
}

Type Guards

Якщо тип не визначений чи невідомий, то розробнику приходить “захист типів”.

typeof

Найпростіший спосіб убезпечити себе від помилки, безпосередньо перевірити тип за допомогою оператора typeof (раніше в прикладах ви могли бачити використання цього оператора, який повертає тип змінної).

const fn = (val: number | string) => {
  if (typeof val === 'number') {
    return ...
  }

  throw new Error(`Тип ${typeof val} не может быть обработан`)
}

in

Ще один із способів захистити тип, використовувати in, цей оператор перевіряє наявність властивості в об’єкті.

const obj = {
  id: 1,
  name: 'first'
}

const bool1 = 'name' in obj  //true
const bool2 = 'foo' in obj  //false

instanceof

Оператор екземпляра перевіряє, чи з’являється властивість прототипу конструктора десь у ланцюжку прототипів об’єкта

function C() {}
function D() {}

const o = new C();

o instanceof C //true
o instanceof D //false

is

Цей оператор вказує TypeScript який тип присвоїти змінній, якщо функція повертає true. У прикладі нижче оператор is звужує тип змінної foo (string | number) до string. Це певний користувачем захист типу. Завдяки захисту компілятор наводить тип до певного всередині блоку if.

interface FirstName {
    firstName: string
}

interface FullName extends FirstName {
    lastName: string
}

const isFirstName = (obj: any): obj is FirstName => {
    return obj && typeof obj.firstName === "string"
}

const isFullName = (obj: any): obj is FullName => {
    return isFirstName(obj) && typeof (obj as any).lastName === "string";
}

const testFn = (objInfo: FirstName | FullName | number) => {
    if (isFullName(objInfo)) {
        console.log('Тип FullName')
    } else if (isFirstName(objInfo)) {
        console.log('Тип FirstName')
    } else {
      console.log('Тип не принадлежит FullName или FirstName')
    }
}

testFn({ firstName: 'Andrey' }) //Тип FirstName
testFn({ firstName: 'Andrey', lastName: 'Maslov' }) //Тип FullName
testFn(1) //Тип не належить FullName чи FirstName

Висновок

Як бачите, TypeScript – це потужний інструмент для розробки, який дозволяє покращити якість вашого коду, зробити його більш надійним та легко підтримуваним. У цьому туторіалі ми розглянули прийоми роботи з TypeScript над такими просунутими темами, наприклад, як дженерики та type guards.

Не забувайте, що вивчення TypeScript – це постійний процес, і чим більше ви практикуєтеся, тим впевненіше використовуватимете його у своїх проектах.

Якщо у вас виникнуть запитання або потрібна додаткова допомога, зверніться до офіційної документації TypeScript або додаткових матеріалів.

Джерело

Цифровий феодалізм. Чи може ШІ скасувати «нове кріпацтво»?

Цифровий феодалізм

Гаспар Кеніг – французький письменник і філософ, засновник руху Simple, який виступає за радикальне спрощення бюрократичного апарату держави. Працюючи над книгою «Кінець індивідуума», він зустрівся з десятками фахівців у галузі штучного інтелекту , щоб дізнатися, які реальні можливості та виклики несуть революційні технології, як вони змінять звичну економіку, політику та наше повсякденне життя. З дозволу видавництва Individuum публікуємо уривок із розділу «На захист права володіння персональними даними». 

У Нью-Йорку я зустрівся з Алексом Еліасом, засновником стартапу Qloo. Він ставить перед собою завдання схрестити індивідуальні переваги в різних областях: якщо вам подобається така музика або такий фільм, ви повинні спробувати такий ресторан або піти на побачення з такою людиною … Qloo міг би стати Netflix для життя, що занурює своїх користувачів у тотальні рекомендації, від яких ніщо не вислизає. У цьому сенсі прагнення до «культурної персоналізації» є саме тим, що лякає мене в ШІ. Але Алекс — інтелектуал зі Східного узбережжя, аматор джазу, який розуміється на перевагах імпровізації. Він знає, що похід у магазин платівок відкриває перед ним несподівані перспективи, тоді як Spotify дає лише обмежений досвід. Проаналізувавши пошук у Qloo, він констатує, що більшість американців вказує як улюблену книгу Біблію, а як улюблений фільм — останній блокбастер… Залишені на милість алгоритму, що оптимізує, вони, ймовірно, підуть найтрадиційнішим шляхом. Ось чому Алекс включив у програму Qloo те, що він називає “фактором диверсифікації”. З одного боку, елемент випадковості вводиться в систему рекомендацій, щоб влаштовувати сюрпризи та викликати питання. З іншого боку, користувач контролює деяку кількість критеріїв: це щоб влаштовувати сюрпризи та викликати питання. З іншого боку, користувач контролює деяку кількість критеріїв: це щоб влаштовувати сюрпризи та викликати питання. З іншого боку, користувач контролює деяку кількість критеріїв: це «перша директива» в дії! Щоб пробудити свідомість, що задрімала, потрібна випадковість, а щоб переорієнтувати алгоритм — наявність чітко вираженого вибору.

Алекс визнає, що надана індивіду влада над власними уподобаннями, як не дивно, робить Qloo менш ефективним і тому менш прибутковим. Зрештою, лаконічно зауважує він, «більшість людей хоче розчинитися в масі». Але він хоча пропонує їм альтернативу, втішаючи себе думкою про те, що нові покоління будуть чутливішими до різноманітності. Крім того, потрібно розраховувати на вільний ринок алгоритмів, щоб викликати до життя проекти, більш уважні до вільного володаря, і сподіватися, що вони поступово завоюють користувачів, залучених перспективою звільнення. А поки що кожен може спробувати перехитрити машину. Наприклад, користуючись Google Map, я завжди відключаю геолокацію: отримуючи користь із розрахунку відстаней, я хочу сам визначати вулиці, щоб розуміти, куди їду, а не сліпо слідувати за синьою кулькою. У Deezer я намагаюся вибирати композиції зі списку, критерії якого встановив сам (наприклад, «сонати»), не покладаючись на рекомендації. Я сам наголошую на дні народження своїх (справжніх) друзів у щоденнику і не чекаю, поки мені нагадає про них LinkedIn. А ще я йду з ютуба, коли закінчується відео, яке я вибрав, хоча зробити це непросто — адже так легко і приємно віддаватися потоку образів.

Але всі ці хитрощі смішні, тому що ринок підтасований. Оскільки платформи мають практично вільний доступ до наших персональних даних, все наше цифрове життя ми займаємося тим, що живимо різні ШІ, які у відповідь нами маніпулюють. Nudge усюди, він не залишає жодної можливості для виваженого та самостійного рішення, з’являючись у формі реклами, повідомлень, рекомендацій, повідомлень у соціальних мережах чи спаму у поштових скриньках. Наш мозок постійно піддається хакінгу, який став можливим завдяки тому, що ми скрізь розкидаємо свої дані. Відкрити інтернет — це як опинитися без штанів у публічному місці, подібно до короля з казки Андерсена: він вважав, що на ньому вбрання з дорогоцінної тканини, а насправді було зовсім голим. У цьому може справді переконатися кожен. Браузер, розроблений стартапом myCo, наприклад, дозволяє візуалізувати всіх чужинців, присутніх на сайті, збирає куки та ін. щоб краще інтерпретувати та спрямовувати мою поведінку. Це пограбування абсолютно законне: протягом дня кілька разів ставлячи галочку «Я згоден» у користувацьких угодах, ми добровільно йдемо на те, щоб бути під ковпаком біля платформ. Хитростям, які сайти та програми використовують для того, щоб збирати наші дані, немає числа. Так, програма, що включає ліхтарик на вашому смартфоні, в обмін на цю крихітну послугу забирає всі ваші дані з геолокації. Пам’ятаю, як сидів у ресторані в Парижі навпроти підприємця, який з гордістю оголосив про свій новий «інноваційний проект» — стежити за пересуваннями миші екраном, щоб відточити профіль користувачів. На моє запитання, чи не надто нав’язливий характер носить ця технологія, він знизав плечима і відповів, що вона послужила б хорошу службу всім нам, після чого почав обговорювати зі своїм сусідом по столу проблеми благодійності. Тартюфи 2.0 явно заслуговують на нову п’єсу…

Ну і як тоді «цифрові» громадяни можуть ретельно відбирати алгоритми, якщо кожним своїм кліком, кожним відкриттям програми вони дають ШІ зброю проти себе? Якщо нам не вдасться тримати наші дані при собі, ми потрапимо під владу могутніх ШІ, які унеможливлять будь-який вільний вибір, а отже, і появу будь-яких альтернатив. Європейський загальний регламент захисту даних (GDPR) спробував було ввести свого роду контроль, вимагаючи більшої прозорості від інтернет-компаній. Однак у результаті нам ще частіше доводиться кликати на «Я згоден», але при цьому ми так і не отримали жодної реальної можливості заперечувати умови чи вести переговори.

[…]

Якщо ми хочемо зрозуміти, як влаштовано цифрове пограбування, жертвами якого ми сьогодні стали, достатньо почитати роботи Жоржа Дюбі про економіку Середньовіччя. На початку попереднього тисячоліття кріпаки, прив’язані до землі, віддавали феодалу основну частину плодів своєї праці в обмін на «безкоштовні послуги», більш-менш реальні: захист під час війни або користування сільською інфраструктурою, що належить феодалу (піччю, млином, давильним пресом). Потрібно було дуже багато часу, щоб селяни поступово отримали право передавати майно у спадок, вільно торгувати плодами своєї праці і, нарешті, відчужувати їх за наявності документів про право власності, яке може перепоступатися. Велика французька революція поклала край феодальної ленной системі і розширила декларація про володіння землею: кріпак став вільною людиною. За кожної технічної інновації спалахують схожі дебати. Через кілька століть після винаходи друкарства Бомарше очолив боротьбу письменників за визнання авторських прав. Під час промислової революції винахідники досягли створення справжнього патентного режиму. Людина завжди повинна боротися за право вільно розпоряджатися своєю власністю та плодами своєї творчості, будь вони матеріальними чи інтелектуальними.

Сьогодні ми стали цифровими кріпаками, передавши право на збирання всіх наших даних в обмін на безкоштовні послуги (цінність яких не завжди однозначна), що надаються нашими новими феодалами. Ми постимо по мільярду фотографій у фейсбук щодня. Саме так по мільярду. Після обробки алгоритмами, в які інтегровано розпізнавання осіб, ця скарбниця даних приносить щоквартальний прибуток близько кількох мільярдів доларів. Який відсоток від неї потрапляє до вихідного виробника? Ніякий. Ну хіба що чайові у вигляді мережі друзів… Ми не тільки не можемо вести переговори з нашим феодалом щодо даних, нам заборонено навіть продавати їх на ринку: у травні 2018 року Олі Фрост, заповзятливий британський мілініал, який виставив на eBay свої посади у фейсбуці десять років, був змушений зняти свою пропозицію як таке, що порушує умови користування соціальною мережею. Однак перебіг міркувань Олі Фроста здавався надзвичайно переконливим: «Оскільки всі заробляють гроші на моїх персональних даних, чому б мені не заробляти їх самому?» Ставки на аукціоні сягнули 400 доларів, але феодал явно було змиритися з подібним порушенням його прерогатив. Воно й зрозуміло: за даними Європейської комісії, вартість персональних даних у 2020 році наблизилася до трильйона євро, тобто до 8% ВВП Європейського Союзу. Хто ж захоче ділитися цією небесною манною зі збродом, який її виробляє? але феодал явно було змиритися з подібним порушенням його прерогатив. Воно й зрозуміло: за даними Європейської комісії, вартість персональних даних у 2020 році наблизилася до трильйона євро, тобто до 8% ВВП Європейського Союзу. Хто ж захоче ділитися цією небесною манною зі збродом, який її виробляє? але феодал явно було змиритися з подібним порушенням його прерогатив. Воно й зрозуміло: за даними Європейської комісії, вартість персональних даних у 2020 році наблизилася до трильйона євро, тобто до 8% ВВП Європейського Союзу. Хто ж захоче ділитися цією небесною манною зі збродом, який її виробляє?

Дивно, наскільки пасивно ми приймаємо цей цифровий феодалізм… Ймовірно, кріпаки XII століття навіть не мріяли про те, щоб оскаржувати права сеньйора, що лежить під своїм балдахіном, — фігури так само священної, що й сьогоднішній підприємець із технологічного сектору на сцені TED Talk. Але оскільки все прискорюється, революція може статися швидше. Право власності на персональні дані, що поки що не існує ніде у світі, поклало б край цьому пограбуванню. Воно включало б виробника даних у ланцюжок виробництва вартості в цифровій економіці, дозволяючи йому монетизувати (або не монетизувати) свої дані згідно з умовами договору, які він обере і які посередники від його імені обговорюватимуть із платформами. Питання про винагороду видається мені другорядним. Важливіше інше: згідно із законом повернувши собі власність на свої дані, людина з новою силою відчує, що вона існує, як селянин, який відчуває задоволення від того, що обробляє «свою» землю. Він має право не вирощувати на ній нічого, крім ожини, будяка і терну, або, у разі даних, має право відмовитися від їх надання, не віддаючи їх в обробку ШІ. Кожен зможе вибирати, що він приховує і на який час, що віддає без дублікатів і кому, що продає за якою ціною. Створивши такий простір індивідуального суверенітету, ми знову станемо собою.

[…]

Сучасна ідеологія шерингу, хоч би якою привабливою вона була, маскує масовий грабіж на користь агрегаторів даних. Регулювання — таке, яке передбачає «Регламент захисту даних», — встановило в цьому будинку двері, але не замок: воно лише змушує нас все частіше кликати по «Я згоден». Відтепер усі ці чужі люди запитують у нас: Я зайду на хвилинку, якщо ви не проти? — вже переступивши поріг. Їм важко відмовити. Право власності на дані встановить на двері замки, перевернувши владні відносини і створивши зону спокою, необхідну для розвитку незалежної особистості. Господар наперед складе список гостей, поставивши договірні умови, на яких він готовий повідомляти свої дані. Гоббс в Левіафані питав: хто, лягаючи спати, не зачинятиме двері на ключ? «Однак ніхто з нас не звинувачує людську природу саму собою. Бажання та інші людські пристрасті власними силами є гріхом». Ніхто не ображатиметься на платформи за те, що вони збирають дані, які ми їм даруємо від щирого серця. Але настав час діяти прагматично і поставити замок, якщо ми хочемо зберегтися як індивіди в епоху ШІ.

Зокрема, можна припустити, що дані кожного зібрані в особистому цифровому гаманці. Ми наперед встановимо у смарт-контракті наші власні умови користування, плід особистої деліберації. Як, з ким та в обмін на що ми готові ділитися нашими особистими даними та якими саме? Різні сайти, програми та платформи, зв’язавшись з нами, тут же будуть проінформовані про наші умови. Це вони повинні їх приймати, а не навпаки. Наприклад, я можу вирішити безкоштовно надати дані про своє здоров’я для дослідницьких цілей, але притримати всі дані про геолокацію, хай навіть мені доведеться оплачувати сервіси на кшталт Waze, які їх сьогодні використовують. Щодо даних про мої електронні покупки, я погоджуся передавати їх без особливих проблем, щоб отримувати рекомендації, заточені під мене (і під час справи мати за це грошову компенсацію). Щось на кшталт блокчейну могло б забезпечити можливість відстеження моїх даних, щоб зберігати «пам’ять» про вихідні умови мого договору: подібна процедура вже використовується у музичній індустрії для охорони прав інтелектуальної власності на музичні композиції. Нескінченні фінансові потоки порядку мікросантиму безперервно створюватимуть дебет і кредит у нашому цифровому гаманці, і при цьому обов’язково з’являться посередники для переговорів щодо вартості даних, за зразком товариств з охорони авторських прав. На зміну цифровому феодалізму прийде ціла економіка нескінченно малого ринку, яка сама керуватиметься ШІ. подібна процедура вже використовується у музичній індустрії для охорони прав інтелектуальної власності на музичні композиції. Нескінченні фінансові потоки порядку мікросантиму безперервно створюватимуть дебет і кредит у нашому цифровому гаманці, і при цьому обов’язково з’являться посередники для переговорів щодо вартості даних, за зразком товариств з охорони авторських прав. На зміну цифровому феодалізму прийде ціла економіка нескінченно малого ринку, яка сама керуватиметься ШІ. подібна процедура вже використовується у музичній індустрії для охорони прав інтелектуальної власності на музичні композиції. Нескінченні фінансові потоки порядку мікросантиму безперервно створюватимуть дебет і кредит у нашому цифровому гаманці, і при цьому обов’язково з’являться посередники для переговорів щодо вартості даних, за зразком товариств з охорони авторських прав. На зміну цифровому феодалізму прийде ціла економіка нескінченно малого ринку, яка сама керуватиметься ІІ.

Фінансовий аспект, який передбачається правом власності, ставить закономірні питання. З одного боку, чому ми повинні платити, хай і дуже скромну суму, за послуги, які досі надавалися безкоштовно? Хіба мало заборонити використання особистих даних у комерційних цілях, у логіці «Регламенту про охорону даних»? Але тоді розвалиться вся модель цифрової економіки, позбавивши нас численних послуг, які може надати ШІ. Якщо ми вважаємо, що за виробництво вартості належить винагорода, тоді ця логіка торгового обміну повинна однаково застосовуватися і до індивіда, який виробляє дані, і до платформи-агрегатора. Якщо Waze вибирає для мене найкращий маршрут, але при цьому я відмовляюся від реклами ресторанів, що знаходяться на цьому маршруті, необхідно знайти інші способи відшкодування шкоди платформам. В іншому випадку я стану «безбілетником», який користується чужими даними, нічим не поділяючись натомість. Анонімність має власну ціну.

[…]

На боці ШІ власність на особисті дані призведе до втрати ефективності, з чим доведеться упокоритися всьому суспільству. Будь-кого порадує, що прибутки Facebook постраждають через втрату точності в таргетуванні реклами, проте та сама неоптимальність торкнеться й інших громадських послуг. Можна, звичайно, уявити, що окремі категорії особливо важливих для суспільства даних будуть «націоналізовані», подібно до того, як дозволено вилучати землю у приватних землевласників для будівництва життєво важливих об’єктів інфраструктури. Але така процедура може мати лише надзвичайний характер, і рішення про неї має прийматися судом, який встановить, якою мірою експропріація відображає мотив загального інтересу. В інших випадках доведеться визнати, що розумне місто чи розумні лічильники вже не будуть настільки розумними, а безпілотні автомобілі настільки безпілотними. Допустивши можливість індивідуального відхилення, право власності на дані викличе аварії, вуглецеві викиди та розриви відносин. Воно завадить суспільству стати ідеальним, повернувши цим можливість еволюції… як регресії. Терпіти подібні випадковості, безпосередні та конкретні, заради розпливчастої обіцянки прогресу — тяжкий тягар для законодавців. Але саме на цій лінії розлому відбувається боротьба міжnudge і автономією, щасливим рабством та поверненням епохи освіти.

Вже зараз є чимало стартапів, які б хотіли взяти участь у цій війні за повернення людині автономії. Такі екосистеми особливо динамічно розвиваються у Франції — країні, яка вигадала авторське право. У Парижі, Ліоні, Монпельє підприємці прагнуть вдихнути життя в це право власності, в якому регулятор поки що відмовляє. Одні розробляють data wallet: використовуючи передбачене GDPR право на мобільність, він дозволяє кожному отримувати свої особисті дані та контролювати їх надання. Інші шукають спосіб надати персональним даним грошову вартість, користуючись правовими «сірими зонами». Треті організують «цифрові кооперативи», які спільно використовують дані своїх членів і виплачують їм дивіденди. Як це вже неодноразово бувало, технологія змусить право підлаштовуватися під себе. Можливо, об’їхавши всю планету, в результаті я знайду рішення зовсім близько від будинку, як капітан Хеддок, який знайшов скарби Лікорну у Муленсарі?

Джерело

Rematch – Redux без шаблонного коду

rematch У цій статті я пропоную вам ознайомитись з основними перевагами Rematch та покажу, як просто та ефективно використовувати його для керування станом ваших додатків. Думаю, що, незалежно від вашого досвіду у розробці, ви знайдете корисну інформацію, яка допоможе вам у повсякденній роботі.

Rematch пропонує зручний синтаксис та дозволяє уникнути написання численних бойлерплейтів, властивих Redux. За допомогою нього ви можете швидко створювати та організовувати Redux-сховище, заощаджуючи при цьому час та спрощуючи процес розробки. Rematch ідеально підходить для різних типів проектів, незалежно від їх розміру та складності.

За допомогою Rematch ви можете визначити моделі (models) та їх стан, ефекти (effects) та ред’юсери (reducers). Він пропонує зручні інструменти для роботи з асинхронними операціями, а також можливість створення селекторів (selectors) для вибірки даних зі сховища. Все це допомагає організувати логіку вашої програми та керувати її станом з мінімальними зусиллями.

Насамперед, я б рекомендував цю бібліотеку тим, хто тільки починає вивчати управління станом додатків або пише новий проект з нуля, тому що Rematch набагато простіше в освоєнні, ніж багато інших бібліотек, забезпечує набагато приємніший інтерфейс і, до того ж, набагато легше.

Введення в Rematch

Rematch – це інтуїтивний та легковажний фреймворк для керування станом вашої веб-додатки на основі Redux. Він пропонує простий та ефективний підхід до організації та управління Redux-сховищем, скорочуючи кількість зайвого коду та спрощуючи розробку.

Rematch — це інструмент для управління станом, а й філософія розробки. Він ставить собі завдання зробити код більш зрозумілим, легко підтримуваним і масштабованим. Однією з ключових особливостей Rematch є його інтеграція з Redux без необхідності писати численні бойлерплейт-коди та налаштування. Це дозволяє розробникам швидше почати ним користуватися та зосередитися на бізнес-логіці своєї програми.

У процесі роботи з бібліотекою я наголосив на наступних її корисних рисах:

  • невеликий обсяг (менше 2Кб);
  • відсутність необхідності зміни;
  • вбудована підтримка сайд-ефектів;
  • підтримка Redux Devtools, TypeScript;
  • підтримка динамічного додавання ред’юсерів, гарячого перезавантаження;
  • можливість створення кількох сховищ;
  • розширюваність функціоналу за допомогою плагінів;
  • можливість використання у React Native.

Якщо порівнювати Rematch із прямим використанням Redux, його основні переваги:

  • Простота та зрозумілий синтаксис . Rematch пропонує просту та інтуїтивно зрозумілу модель, яка дозволяє визначити моделі стану, ефекти та редьюсери з мінімальною кількістю коду. Він звільняє розробників від необхідності писати численні дії (actions), константи та редьюсери, що робить код лаконічнішим і зрозумілішим.
  • Модульність і перевикористовуваність . Rematch дозволяє організовувати код вашої програми у модулі (моделі), що сприяє логічному поділу функціональності та повторному використанню коду. Ви можете створювати незалежні моделі, що містять свій стан, ред’юсери та ефекти, та комбінувати їх в одне сховище.
  • Потужні ефекти . Rematch надає простий спосіб визначення та обробки асинхронних операцій та сайд-ефектів за допомогою ефектів. Він інтегрується з middleware Redux, що дозволяє легко керувати асинхронними запитами, зверненнями до API та іншими ефектами сайду.
  • Розширюваність . Rematch дозволяє легко розширювати функціональність за допомогою плагінів. Ви можете використовувати готові плагіни або створити свої власні, щоб додати нові можливості та інтеграції у свою програму.

Незважаючи на представлені плюси, важливо розуміти, що Rematch – це лише обгортка над Redux, яка надає розробникам спрощене API. Проблеми продуктивності та додаткового функціоналу, на жаль, не вирішить перехід від використання Redux до Rematch.

Основні концепції Rematch

Тут я покажу основні концепції Rematch, які допоможуть вам організувати та керувати станом вашої програми.

Моделі (Models)

Моделі є ключовим поняттям у Rematch. Вони є незалежними блоками коду, що містять стан, ред’юсери та ефекти. Кожна модель має унікальне ім’я і може бути поєднана з іншими моделями в одне сховище (store).

Давайте створимо просту модель “counter”, яка міститиме стан лічильника та редьюсери для його збільшення та зменшення, а також ефект для асинхронного збільшення:

/* ./models/count.ts */

import { createModel } from "@rematch/core";
import { RootModel } from ".";

export const count = createModel<RootModel>()({
  state: 0, // початковий стан
  reducers: {
    increment(state, payload: number) {
      return state + payload;
    },
    decrement(state, payload: number) {
      return state - payload;
    },
  },
  effects: (dispatch) => ({
    async incrementAsync(payload: number, state) {
      await new Promise((resolve) => setTimeout(resolve, 1000));
      dispatch.count.increment(payload);
    },
});

export default counter;
import { Models } from "@rematch/core";
import { count } from "./count";
import { example } from "./example";

export interface RootModel extends Models<RootModel> {
  count: typeof count;
  example: typeof example;
}

export const models: RootModel = { count, example };

Сховище (Store)

Сховище є об’єднання декількох моделей в одну структуру даних. Воно є єдиним джерелом правди для вашої програми та зберігає стан усіх моделей.

Для створення сховища Rematch використовує функцію init, яка приймає об’єкт із моделями:

import { init, RematchDispatch, RematchRootState } from "@rematch/core";
import { models, RootModel } from "./models";

export const store = init({
  models,
});

export type Store = typeof store;
export type Dispatch = RematchDispatch<RootModel>;
export type RootState = RematchRootState<RootModel>;

Диспатч екшенів (Dispatch actions)

За допомогою диспатча ви можете викликати редьюсери та ефекти ваших моделей. Диспатч можна викликати звичним способом, як у Redux, або коротким записом:

const { dispatch } = store;

dispatch({ type: "count/increment", payload: 1 });
dispatch.count.increment(1);

dispatch({ type: "count/incrementAsync", payload: 1 });
dispatch.count.incrementAsync(1);

Доступ до стану та дій

Щоб отримати доступ до стану та дій моделей у компонентах вашої програми, ви можете використовувати хук useSelector та метод dispatch:

import * as React from "react";
import { useSelector, useDispatch } from 'react-redux';
import { RootState, Dispatch } from './store';

const CounterComponent = () => {
  const count = useSelector((state: RootState) => state.count);
  const dispatch = useDispatch<Dispatch>();

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => dispatch.count.increment(1))}>Increment</button>
      <button onClick={() => dispatch.count.decrement(1))}>Decrement</button>
    </div>
  );
};

export default CounterComponent;

У цьому прикладі ми використовуємо хук useSelector для отримання значення стану “counter” зі сховища, а також метод dispatch для виклику відповідних редьюсерів.

Ефекти (Effects)

У Rematch ефекти надають можливість виконувати асинхронні операції, такі як запити до сервера чи обробка даних. Вони дозволяють вам легко керувати побічними ефектами у вашому додатку.

Для додавання ефектів у модель можна використовувати ключове слово effects і визначити потрібні методи. Давайте додамо ефект для завантаження даних із сервера:

const counter = createModel<RootModel>()({
  state: 0,
  reducers: {
    // ...
  },
  effects: {
    async fetchData(payload, rootState) {
      try {
        const response = await fetch(`http://example.com/${payload}`);
        const data = await response.json();
        // Дії з отриманими данными
      } catch (error) {
        // Обробка помилок
      }
    },
  },
});

Плагіни (Plugins)

Rematch надає можливість розширення функціональності за допомогою плагінів. Плагіни дозволяють додавати додаткові можливості або змінювати поведінку Rematch, щоб краще відповідати вашим потребам. Вони можуть перевизначити конфігурацію, додати нові моделі або навіть замінити все сховище.

Існує безліч плагінів, доступних для використання з Rematch. Деякі з них були написані безпосередньо командою авторів цієї бібліотеки, але є такі, які створювалися спільнотою, на npm/github, і ніхто не забороняє написати свій власний плагін.

Нижче ви знайдете короткий опис плагінів, створених командою Rematch:

  • @rematch/immer : Обертає ваші ред’юсери за допомогою бібліотеки immer, що дозволяє безпечно виконувати зміни стану за допомогою мутацій, зберігаючи при цьому незмінність стану.
  • @rematch/select : Додає можливість використовувати селектори (selectors) для вибору даних стану. Селектори створюються за допомогою бібліотеки reselect за замовчуванням і автоматично зв’язуються із залежностями селекторів з інших моделей.
  • @rematch/loading : Плагін для відображення індикаторів завантаження під час виконання ефектів. Допомагає уникнути ручного керування станом завантаження, додаючи автоматичну підтримку завантаження Rematch.
  • @rematch/updated : Плагін, що дозволяє підтримувати тимчасові мітки (timestamps) під час виклику ефектів. Він застосовується переважно для оптимізації ефектів і може використовуватися для запобігання виконання дорогих запитів протягом певного періоду часу або обмеження частоти виконання ефектів.
  • @rematch/persist : Надає автоматичну персистентність стану Redux. Це дозволяє зберігати стан між перезавантаженнями сторінки або після закриття та повторного відкриття програми.
  • @rematch/typed-state : призначений для перевірки типів стану під час виконання. Використовує proptypes для опису очікуваної форми типів.

Підсумок

У цій статті я розповів про Rematch – потужну бібліотеку для управління станом додатків. На підставі свого досвіду виділив основні переваги Rematch і на практиці показав, як легко та ефективно використовувати його для організації Redux-сховища та управління станом.

Rematch пропонує простий та зручний синтаксис, який значно зменшує кількість бойлерплейту, пов’язаного з Redux, і я думаю, що це може зробити його привабливим інструментом для простих розробників, які хочуть зосередитися на розробці програми, а не на складностях управління станом.

Завдяки підтримці безлічі плагінів, Rematch може бути легко розширений та адаптований під ваші конкретні потреби. Ми розглянули деякі популярні плагіни, такі як плагін для збереження стану за допомогою redux-persist, плагін для використання immer.js та плагін для створення селекторів за допомогою reselect.

Зазначу, що Rematch постійно розвивається та покращується, і ви можете досліджувати додаткові можливості, вивчивши вихідний код плагінів або створюючи власні плагіни.

Сподіваюся, що ця стаття допомогла вам зрозуміти переваги та можливості Rematch та надихнула вас використовувати його у ваших проектах. Бібліотека пропонує простоту, компактність та масштабованість, роблячи процес розробки більш ефективним та приємним.

Джерело

Відмінності базових елементів блокчейн: чому ця технологія не здатна здійснити революцію

blockchain

Такі слова, як Біткоїн та блокчейн іноді використовуються як взаємозамінні, але насправді між ними є деякі непорозуміння. Такої думки дотримується Кевін Вербах, професор юридичних наук та ділової етики Уортонської школи бізнесу. Він заявив про те, що в технології блокчейн базові елементи мають певні відмінності, при цьому йдеться про криптовалюту, криптоаналіз і саму блокову систему.

У наші дні важко не помітити ажіотажу навколо заяв про те, як криптовалюти та технологія blockchain можуть змінити все (або принаймні зробити багато). Тим не менш, такий галас навколо цього є ризиком масштабної афери, марною і небезпечною. Дивно, що така величезна аудиторія досі не розуміє, що відбувається. Однією з головних причин плутанини є те, що всі говорять про різні речі.

Представники угруповань усіх трьох складових блокчейну поділяють базовий набір принципів проектування та технологічних основ, але в цілому їх цілі та перспективи практично повністю відрізняються один від одного. Спробуймо розібратися в ситуації.

Існує криптовалюта — ідея, що мережі можуть безпечно передавати цифрові активи без центральних точок контролю. Існує блок-ланцюжок — ідея про те, що мережі можуть колективно досягати консенсусу щодо інформації через встановлені межі довіри. І є криптоаналіз — ідея про те, що віртуальні валюти можуть відігравати роль активів, що торгуються.

Перше – воістину революційне поняття, але це ще не знає, що революція буде успішною. Друге та третє — інновації, що змінюють гру та здатні до суттєвого еволюціонування.

Криптовалюти

Цифрові гроші — це те, про що багато хто, напевно, чув найбільше, починаючи з Bitcoin. Найпростіший спосіб зрозуміти їх – не вивчати деталі майнінгу чи внутрішнього пристрою. Натомість краще зосередитися на децентралізації довіри.

Багато дій потребують довіри. Без довіри проект закону вартістю кілька мільйонів доларів — це лише аркуш паперу, а голосування на виборах — безглуздий ритуал. Традиційно під словом «довіра» малася на увазі залежність від партнерів, установ чи посередників. Ці централізовані архітектури довіри є сильними. Серед іншого, вони принесли нам сучасну індустріальну цивілізацію. Але є й недолік у довірі. Він має на увазі вразливість. Люди, уряди та компанії, яким ми довіряємо, можуть виявитися ненадійними з низки причин. Біткоїн показав, що можна створити щось цінне (наприклад, гроші), яким можна довіряти без необхідності довіряючи конкретній особі чи організації, зокрема щодо перевірки транзакцій.

Ця ідея, якщо вона буде повністю реалізована (у разі «якщо» несе у собі крані важливий сенс), може змінити суспільство. Світ може отримати прозорі компанії, які справді відображають волю зацікавлених у їхньому розвитку сторін, уряди, які справді відображають волю своїх громадян, та інтернет, звільнений від цензури та впливу ззовні. Це здатне покласти край фейковим новинам та масової автоматизації повсякденного життя для покращення рівня життя людства. Або принаймні люди можуть отримати рішення, які помітно покращать їхній статус-кво. Децентралізація несе у собі цінність у вигляді незалежно від способу.

Витрати

Цей термін застосовується практично до всіх сфер діяльності. Для Біткоіна витрати пов’язані з дуже повільною мережею з обмеженою функціональністю, яка витрачає величезну кількість електроенергії та збагачує співтовариство майнерів. Можливо, це того варте. Однак, можливо, у майбутньому технологічні рішення завдяки удосконаленню блокової технології призведуть до зниження витрат. Поки що ми цього не знаємо. Так, ринкова капіталізація Біткоїна становить мільярди доларів, але це насправді просто криптоаналітичне мислення. Хтось використовує його, щоб робити щось, окрім прагнення розбагатіти шляхом торгівлі чи уникнути уваги з боку правоохоронних органів? Він стає все гіршим і гіршим, тому що на ринку з’являються все нові і нові криптовалюти. Деякі з них не поступаються,

Прибуток

Що справедливо для невеликих груп, обмежених програм та «особливих» користувачів, не обов’язково може стати мейнстримом. Доки не з’явився Facebook, було неясно, хто і як може заробляти реальні гроші на соціальних мережах, які спочатку були місцем простого спілкування підлітків і молоді. Однак сам факт появи Facebook не доводить, що це було неминучим.

Деякі зі ставок на криптовалютну революцію можна довести правильно. Такі ставки мають широкий потенціал зростання, але насправді це все ж таки просто гра. Насправді реальні революції відбуваються не так часто. І коли це трапляється, то відбувається із серйозними побічними збитками.

Blockchain

Блокчейн має спільне коріння з криптовалютами, але його мета зовсім інша. Замість спроби уникнути довіри блокчейн прагне надмірно обмежити довіру. Ми справді довіряємо собі чи своїй власній організації. Але жодна людина чи компанія не є островом в океані. Але навіть острівні держави змушені взаємодіяти з іншими учасниками світу через воду.

Світ наповнений процесами, особливо серед великих компаній та урядів, де їх слід відстежувати з однієї довіреної зони до іншої. Фірми щорічно витрачають близько $10 трлн на «логістику», що скорочує витрати на транспортування через системи, контрольовані кимось. Виробники, дистриб’ютори та роздрібні торговці зберігають власні надійні (але незалежні) записи даних про потоки через ланцюжки поставок.

Коли пацієнт йде в нову лікарню або до нового лікаря, то не маєте при собі всіх медичних записів через відсутність єдиної бази. Усі такі недоліки в потоці інформації є своєрідними транзакційними витратами. Відповідно до сьогоднішньої домінуючої школи економіки, зусилля зі знищення цієї проблеми є важливою рушійною силою в економіці.

Значна частина транзакційних витрат між фірмами (іноді і всередині них) випливає з обмеженої еластичності довіри. Якщо кожна сторона транзакції довіряє залученій інформації, навіть якщо вони не довіряють одна одній, витрати можуть знизитися, а продуктивність різко змінитись. У цьому полягає суть бачення блочної ланцюжка.

Багато відомих компаній вже беруть участь у всіх процесах блокових випробувань і консорціумах, тому що бачать у цьому величезний потенціал. Децентралізація в цьому випадку має інше бачення, а не просто базову вимогу, як у випадку з криптовалютами.

Криптоаналіз

Під цим терміном розуміється аналіз цифрових токенів, які перетворюються на інструменти торгівлі. Потенційна шкала цього напряму величезна. Обсяги ринків досягають трильйони доларів, що не можна назвати незвичайним у сучасній фінансовій сфері. При цьому вони розглядаються не як спосіб полегшення дій без централізованої довіри, а як новий клас інвестиційних активів. Оскільки вони є цифровими, вони можуть теоретично торгуватися більш ефективно, ніж існуючі інструменти. За своєю суттю вони гнучкіші і глобальніші. Практично всі основні гравці Уолл-стріт прагнуть взяти участь у різних стартапах у ролі інституційних інвесторів.

Як тільки буде встановлено фундаментальне значення цифрових токенів у децентралізованій мережі, чому б просто не використовувати їх для заробляння грошей? У будь-якому випадку вони залежатимуть від криптовалюту, бо торгівля можлива лише чимось справді цінним. Однак вони також мають бути безпечними. Але криптоаналіз ігнорує чи відкидає ідею криптовалют про те, що довіра — «майже непристойність» (вирізка з цитати експерта, який робив початковий аудит безпеки Біткоіна ). Для трейдера криптоаналіз довіри та відсутність довіри — це не що інше, як засіб для досягнення мети, що називається ліквідністю.

Інший спосіб подумати про це полягає в тому, що криптоаналіз передбачає свого роду злиття функцій токенів та криптовалют. Якщо ви хочете використовувати Біткоїн для оплати покупок, Ефіріум для придбання обчислювальних циклів для розподілених додатків, Filecoin для покупки хмарного сховища файлів або Augur Rep для перевірки результатів ринків прогнозів, ви забезпечуєте цінність цих токенів на основі того, що ви отримуєте за рахунок їх використання.

Теоретично велика потреба у використанні додатків означає скорочення пропозицій і зростання попиту, що штовхає курс вгору. На практиці поки що жодна з додатків не має істотної важливості, тому ціна токенів залишається дуже спекулятивною. Спекуляцію не обов’язково завжди розглядати як щось погане. Це апетит до ризику, який керує фінансовими ринками. Однак іноді спекуляція стимулює ринки рости надто високо. Ключовим питанням для криптовалют є питання про те, чи можна буде контролювати такі умоглядні інстинкти.

У процесі розвитку ринків можуть виникати різні цікаві можливості для «токенізації» фізичних предметів, таких як товари, нерухомість, цифрові речі, такі як інтелектуальна власність та інші види прав, з використанням інструментів фінансової інженерії та аналітики. У цьому напрямі Уолл-Стріт розвивається вже багато років, створюючи необхідні основи.

Не варто перетинати межу

Історії не є взаємовиключними як такі. Успіх чи невдача якогось бачення не обов’язково означають, що аналогічне може статися з іншим. Криптовалюти мають найруйнівніший потенціал, бо вони обіцяють децентралізувати владу. Це також створює великі перешкоди для їхнього успіху.

Як блокові системи, і цифрові валюти зменшують децентралізацію серед інших своїх переваг. Вони різняться в цілях і можуть мати значні можливості, але їх потрібно оцінювати зі свого погляду. Наприклад, чи варто розглядати ICO як нову форму краудфандингу чи спосіб започаткувати децентралізовану економіку? Те, що вважається успішним чи невдалим, виглядає по-різному залежно від відповіді.

Будь-які судження про успіхи або невдачі, пов’язані з блоковою технологією, повинні бути сформульовані з точки зору відповідної підкатегорії. Коли спостерігачі вказують на прийняття блокчейна тією чи іншою компанією або високі ціни на криптовалюти як доказ їхньої життєздатності, вони перетинають межу. Той факт, що у світі ICO існує масове шахрайство та крадіжки, ніяк не належить до низки урядових ініціатив у сфері блокчейну.

Незалежно від того, чи йдеться про бізнес-модель, яка передбачає впровадження блокового ланцюжка в банки, цього недостатньо, щоб говорити про перспективи децентралізованих автоматизованих організацій загалом.

Чим раніше ми перестанемо розглядати блокчейн і криптовалюти як унітарне явище, тим точніше і якісніше ми зможемо оцінити події, що відбуваються.

Джерело

Співвідношення ризику та прибутку при торгівлі криптовалютою та чому це важливо

Співвідношення ризику та прибутку

  • Співвідношення ризику та прибутку – коефіцієнт, призначений для розрахунку потенційної прибутковості від торгової угоди щодо закладеного ризику та з урахуванням стратегії трейдера. RR дозволить зрозуміти, чи є угода вигідною чи ні.
  • Співвідношення ризику та прибутку розраховується після складання торгового плану, визначення точок входу та виходу та рівня встановлення стоп-лосса.
  • Співвідношення ризику та прибутку розраховується індивідуально для кожної позиції на підставі торгової стратегії трейдера з урахуванням статистики та можливостей.
  • Грамотне співвідношення ризику та прибутку дозволяє заробляти у довгостроковій перспективі при правильному аналізі результатів своєї торгової стратегії.

Що таке співвідношення ризику та прибутку (RR)

Співвідношення ризику та прибутку (Risk/Reward Ratio або RR) – коефіцієнт, що показує співвідношення ризику до потенційного прибутку. Конкретне значення RR розраховується перед покупкою активу та дозволяє оцінити потенціал угоди з погляду торгової стратегії трейдера.

Якщо співвідношення ризику до прибутку більше значення 1, то ризик більший, ніж потенційний прибуток. Коли значення нижче одиниці, то потенційний прибуток більший за закладені ризики.

З погляду трейдингу та інвестицій ризик означає потенційний збиток, який трейдер готовий піти, відкриваючи позицію. Рівень ризику зазвичай контролюють за допомогою виставляння ордерів стоп-лосс (Stop Loss), тобто заявок на автоматичний продаж активу при досягненні певної ціни. Це важливий торговий інструмент, і необхідний як обмеження збитків. Рівень ризику є невід’ємною частиною у процесі обчислення потенційного прибутку трейдера та його торгової стратегії загалом.

Прибуток — це різниця між ціною купівлі активу та ціною, за якою його буде продано. У контексті співвідношення RR прибутком є ​​потенційний рівень, який визначає трейдер перед входом до позиції для оцінки потенціалу торгової операції.

Як правильно розрахувати співвідношення ризику та прибутку

Загальноприйнятий варіант розрахунку коефіцієнта RR визначається як відношення ризику до прибутку, тобто RR дорівнює ризик поділений на прибуток. Хоча деякі трейдери через особисті переваги можуть використовувати зворотний варіант, де прибуток ділять на ризик, ми розглянемо стандартний приклад розрахунку.

Припустимо, що бажаєте придбати актив за ціною $100. Ви також вирішили обмежити ризик, тобто поставити стоп-лосс, на позначці $90, і встановили собі цільову ціну, за якою продасте актив, на позначку $130. У цьому випадку співвідношення RR складе 1 до 3 або коефіцієнт з приблизним значенням 0,33. Тобто ризик менший, ніж потенційний прибуток.

У прикладі з тією ж ціною входу ($100), і такою ж цільовою ціною ($130), але з виставленим стоп-лоссом на відмітці $40, співвідношення RR буде рівним 2. Таке значення коефіцієнта вказує, що ризик значно перевищує очікуваний прибуток.

Оптимальне співвідношення ризику та прибутку

Одним із найпопулярніших значень при розрахунках співвідношення ризику та прибутку є 1 до 3 або коефіцієнт 0,33. Також часто використовуються співвідношення 1 до 7, 1 до 10, 1 до 15.

Однак вибір загальноприйнятих варіантів RR є грубою помилкою у трейдингу. Трейдер повинен сам визначити, яке співвідношення RR найкраще підходить під його торгову стратегію на основі досвідчених даних, статистики, кон’юнктури ринку.

Наприклад, якщо трейдер робить тільки 50% успішних угод, то RR рівний 0,5 або 1 до 2 не принесе користі. Цільова ціна продажу активу перед входом до угоди має статистично приносити трейдеру прибуток, а не тільки саме в цій торговій операції.

У прикладі із співвідношенням 1 до 3 або коефіцієнтом 0,33, сенс RR закладено в тому, щоб одна прибуткова угода могла покрити 3 збиткові угоди. У разі коли співвідношення 1 до 5, то одна прибуткова угода повинна буде покрити 5 збиткових.

Перш ніж оцінювати ризики та проводити розрахунки RR, трейдер оцінює потенціал руху ціни, знаходить точку для входу і становить прогноз руху ціни на актив, також визначивши собі момент виходу з позиції.

Тільки після цього є сенс проводити розрахунки RR. Якщо отриманий коефіцієнт відповідає торговій стратегії трейдера, він входить у позицію.

Навіщо розраховувати співвідношення ризику та прибутку

RR розраховується для того, щоб трейдер міг ефективно використовувати свою торгову стратегію, регулюючи потрібний рівень ризику та прибутку для отримання прибутку на довгому відрізку часу.

Навіть якщо відсоток успішних операцій невеликий, скажімо 20%, грамотне співвідношення ризику і прибутку може принести трейдеру дохід на довгій дистанції.

Відповіді на популярні запитання

Що таке співвідношення прибутку до ризику?

Risk/Reward Ratio або RR – це спосіб оцінити потенціал угоди для трейдера на основі його торгової стратегії та можливостей. Простіше кажучи, RR показує, чи є угода вигідною чи ні на основі потенційних ризиків та прибутку.

Що таке вінрейт у трейдингу?

Вінрейт у трейдингу – ставлення кількості прибуткових угод до збиткових. Наприклад, якщо ви закриваєте 60% угод із прибутком, а 40% — зі збитком, то ваш вінрейт становитиме 0,6 до 0,4, або 1,5.

Що таке 1 до 3 у трейдингу?

1 до 3 у трейдингу – одне з найпопулярніших співвідношень прибутку до ризику у трейдерів. Воно означає, що як мінімум 1 із 4 угод має бути прибутковою. Проте таке співвідношення має відповідати обраній торговій стратегії та співвідноситися з вінрейтом. У деяких випадках оптимальне співвідношення прибуткових угод до збиткових може відрізнятися.

Що таке RR у трейдингу?

RR у трейдингу – абревіатура від англійського терміна Risk/Reward (Ризик/дохідність) і означає співвідношення прибутку до ризику.

Джерело

react-query vs SWR і чи позбудемося ми Redux?

react-query vs SWR

Давайте спочатку познайомимося з обома бібліотеками, щоб порівняти їх і переконатися, що краще. react-query та SWR – це дві популярні бібліотеки для керування станом даних у React-додатках. Вони обидві призначені для полегшення роботи з даними, що отримуються з сервера, але мають деякі відмінності у функціональності та підходах.

react-query

react-query  — це потужна бібліотека для керування станом даних у програмах React. Вона надає прості та ефективні інструменти для роботи з даними, що отримуються з сервера, та спрощує взаємодію з API-запитами. Нижче познайомимося з базовими фічами цієї бібліотеки:

Кешування даних:  Однією з основних можливостей react-query є кешування даних. Під час виконання запитів до сервера бібліотека автоматично кешує отримані дані. Це дозволяє уникнути повторних запитів на сервер при зверненні до тих самих даних у різних частинах програми. Кеш react-query також автоматично інвалідується під час оновлення даних на сервері або вручну за допомогою інвалідності.


queryClient.invalidateQueries()

Автоматичне оновлення даних:  react-query надає механізм автоматичного оновлення даних на основі певних подій. Коли запит на сервер виконується, бібліотека автоматично оновлює кешовані дані при успішному завершенні запиту, мутації або ручних викликах оновлення. Це дозволяє завжди мати актуальні дані у додатку.

Повторні запити:  У разі помилок під час виконання запиту react-query надає механізм повторних запитів, який автоматично спробує повторити запит. Це особливо корисно під час роботи з нестабільним інтернет-з’єднанням або тимчасовими проблемами на стороні сервера. Також можна налаштувати інтервал між повторними запитами або вказати максимальну кількість повторів у налаштуваннях.

Оптимістичні оновлення:  React-query підтримує оптимістичні оновлення даних. Це дозволяє оновлювати кешовані дані негайно ще до того, як запит на сервер буде завершено. Це створює плавне враження для користувачів та підвищує чуйність інтерфейсу.

Обробка помилок та повторні запити:  Бібліотека спрощує обробку помилок під час виконання запитів. Вона надає механізм повторних запитів під час помилок, що дозволяє автоматично спробувати повторити запит для отримання даних. Це особливо корисно під час роботи з нестабільним інтернет-з’єднанням або тимчасовими проблемами на стороні сервера.

Гнучка настройка запитів:  Бібліотека надає гнучкі засоби для налаштування запитів, дозволяючи контролювати кешування, час життя даних, політики повторних запитів та багато іншого.

// 
import { QueryClient } from '@tanstack/react-query';

const queryClient = new QueryClient({
   defaultOptions: {
      queries: {
      staleTime: Infinity,
    },
  },
});

// 
queryClient.setQueryDefaults(
  ['todos'], { staleTime: 3000 }
)

Мутації:  react-query підтримує мутації, що дозволяє легко виконувати зміни даних на сервері. Мутації є особливими функціями, які виконують запити на сервер для зміни даних, і автоматично оновлюють відповідний кеш після успішного завершення мутації.

Інтеграція з React:  react-query розроблена спеціально для роботи з React та інтегрується з ним без проблем. Вона надає хуки та компоненти, які дозволяють зручно взаємодіяти з даними та відображати їх в інтерфейсі React-компонентів.

//
import {
  QueryClient,
  QueryClientProvider,
  useQuery,
} from '@tanstack/react-query'

const queryClient = new QueryClient()

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Example />
    </QueryClientProvider>
  )
}

function Example() {
  const { isLoading, error, data } = useQuery({
    queryKey: ['repoData'],
    queryFn: () =>
      fetch('https://api.github.com/repos/TanStack/query').then(
        (res) => res.json(),
      ),
  })

  if (isLoading) return 'Loading...'

  if (error) return 'An error has occurred: ' + error.message

  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.description}</p>
      <strong>👀 {data.subscribers_count}</strong>{' '}
      <strong>✨ {data.stargazers_count}</strong>{' '}
      <strong>🍴 {data.forks_count}</strong>
    </div>
  )
}
//
import {
  useQuery,
  useMutation,
  useQueryClient,
  QueryClient,
  QueryClientProvider,
} from '@tanstack/react-query'
import { getTodos, postTodo } from '../my-api'

const queryClient = new QueryClient()

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Todos />
    </QueryClientProvider>
  )
}

function Todos() {
  const queryClient = useQueryClient()

  const query = useQuery({ queryKey: ['todos'], queryFn: getTodos })

  //
  const mutation = useMutation({
    mutationFn: postTodo,
    onSuccess: () => {
      // 
      queryClient.invalidateQueries({ queryKey: ['todos'] })
    },
  })

  return (
    <div>
      <ul>
        {query.data?.map((todo) => (
          <li key={todo.id}>{todo.title}</li>
        ))}
      </ul>

      <button
        onClick={() => {
          mutation.mutate({
            id: Date.now(),
            title: 'Do Laundry',
          })
        }}
      >
        Add Todo
      </button>
    </div>
  )
}

render(<App />, document.getElementById('root'))

SWR

SWR  (Stale-While-Revalidate) – це бібліотека для керування станом даних у React-додатках, яка орієнтована на кешування даних та автоматичну валідацію. Вона надає простий та ефективний спосіб роботи з даними, що отримуються з сервера, та спрощує оновлення даних в інтерфейсі програми. Нижче познайомимося з базовими фічами цієї бібліотеки:

Кешування даних:  Однією з основних можливостей SWR є кешування даних, які отримують із сервера. Коли запит на сервер, бібліотека автоматично кешує отримані дані. Це дозволяє уникнути повторних запитів на сервер при зверненні до тих самих даних у різних частинах програми.

Автоматична валідація даних:  SWR використовує стратегію Stale-While-Revalidate, що означає, що вона повертає старі дані з кешу (якщо вони доступні) і одночасно запускає повторний запит на сервер для отримання актуальних даних. Таким чином користувач завжди бачить старі дані, навіть якщо сервер вже повернув нові. Це дозволяє надати користувачеві миттєвий відгук та актуальні дані після завершення повторного запиту.

Повторні запити:  У разі помилок під час виконання запиту SWR надає механізм повторних запитів, який автоматично спробує повторити запит. Це особливо корисно під час роботи з нестабільним інтернет-з’єднанням або тимчасовими проблемами на стороні сервера.

Оптимістичні оновлення:  SWR також підтримує оптимістичні оновлення даних. Це означає, що при оновленні даних на сервері вона моментально оновлює дані в кеші і показує користувачеві оновлені дані без очікування відповіді від сервера. Після успішного завершення запиту на сервер кеш автоматично оновлюється з актуальними даними.

Політики повторних запитів:  SWR дозволяє гнучко налаштовувати повторні запити за допомогою різних політик. Наприклад, можна встановити інтервал між повторними запитами або вказати максимальну кількість повторів.

Інтеграція з React:  SWR розроблена для інтеграції з React і надає хук  useSWR(), який дозволяє зручно взаємодіяти з даними та обробляти стан запитів.

const fetcher = (...args) => fetch(...args).then(res => res.json());

//
import useSWR from 'swr'
 
function Profile () {
  const { data, error, isLoading } = useSWR('/api/user/123', fetcher)
 
  if (error) return <div>Помилка загрузки</div>
  if (isLoading) return <div>загрузка...</div>
 
  //
  return <div>привіт, {data.name}!</div>
}

Тепер, давайте порівнювати ці дві бібліотеки та визначити, який краще вибрати:

Як ми зрозуміли, основний акцент бібліотеки  react-query  робиться на керування даними на клієнтській стороні програми, особливо на роботу з даними, що отримуються з сервера (API-запити). react-query пропонує потужні засоби для кешування даних, автоматичної інвалідності кешу та обробки запитів.

SWR  в першу чергу орієнтована на кешування та автоматичну валідацію даних, які отримують з сервера. Вона надає зручні засоби для кешування та повторних запитів даних із підтримкою стратегії “Stale-While-Revalidate” (збереження старих даних, поки виконується повторний запит).

Також  react-query  надає гнучкі засоби для налаштування запитів та підтримує мутації, дозволяючи легко виконувати зміни даних на сервері, для цього  react-query  надає хуки ( useMutation(),  useQuery()) та компоненти для зручної взаємодії із запитами та мутаціями. SWR  у свою чергу  надає лише один хук —  useSWR, який дозволяє виконувати запити та автоматично кешувати дані, а також обробляти їх оновлення та помилки.

Підсумок

Загалом, якщо ваш проект величезний і має багато  GET/POST запитів, краще використовувати react-query, якщо проект не великий і не має багато запитів, то краще вибирати SWR. Все залежить від обсягу та функціональності проекту.

Тепер відповімо на найголовніше запитання: «Чи позбавимося ми Redux?». Насправді повністю позбутися Redux не вийде, але певною мірою, так, позбудемося. Як? У всіх запитах, де використовується react-query/SWR використовувати Redux не потрібно, ці бібліотеки самі всі дані беруть з бекенда і працюють як “state manager”, а також плюс до цього кешують дані, що це навіть дуже вигідно.

Джерело

Абстрактні типи даних для початківців

Абстрактні типи данних

“У комп’ютерній науці всі проблеми можуть бути вирішені за допомогою додаткового рівня непрямості,” – Девід Вілер

Типи даних – це природно

Людина є істотою з дуже розвиненим образним мисленням. Саме наша здатність до створення абстракцій та узагальнення прожитого досвіду стала ключем до розвитку цивілізації. Ми користуємося цими здібностями від народження, навіть не замислюючись. Наприклад, ми з дитинства працюємо з різними типами даних, діючи швидше інтуїтивно, не даючи їм формального опису. Ми знаємо, що числа можна складати і множити, а зі слів складати речення. Навряд чи нам спаде на думку спробувати перемножувати слова. Таким чином, ми розуміємо, коли бачимо написані символи (літери, наприклад), що ми можемо і чого не можемо робити з цими символами, а також знаємо набір допустимих значень символів — наш алфавіт. У прикладі літери — і є тип даних. Ми знаємо безліч значень літер — вони є алфавітом. Крім того, знаємо, що літери ми можемо складати слова – це операції. Це природне уявлення людини лягло основою формального визначення типу даних.

Тип даних  – безліч значень та [допустимих] операцій над цими значеннями.

Хоча ми в житті не використовуємо це визначення і навіть не замислюємося про це, кожен день ми стикаємося з різними типами даних: літери, цифри, предмети побуту, продукти харчування. Але навіть при вирішенні побутових питань може виникнути ситуація, коли наявних у розпорядженні простих типів даних може бути недостатньо.

Уявіть собі такий діалог матері та маленького сина років трьох, який ще не дуже освоїв абстрактне мислення:

— Синку, принеси, будь ласка, зі столу ручку, мені треба записати щось!

– Мамо, тут немає ручки!

– Тоді олівець.

– І олівця немає.

– А що є?

— Фломастери є й маркер.

– Ну, тоді неси фломастер!

Доросла людина швидше за все відразу принесла б фломастер і сказала: «ручки не було, думаю, фломастер пригодиться». Чому? — Тому що з якогось рівня розвитку абстрактного мислення та вміння взаємодіяти з іншими людьми людина вже розуміє, що в цьому проханні головне не конкретний тип об’єкта — ручка — а її властивість писати по папері. Таку ж властивість мають й інші об’єкти: олівці, фломастери, маркери, навіть шматочок вугілля. Таким чином, він машинально поєднує кілька типів інструментів в один тип: те, чим можна писати. Це вміння часто спрощує нам повсякденне життя та спілкування з оточуючими, при цьому дещо віддаляючи нас від конкретних фізичних об’єктів. Щоб дістатися роботи, ми використовуємо «громадський транспорт» — маршрути та конкретні вагони чи машини можуть бути різними, але головне, що вони мають потрібні нам властивості: ми можемо увійти, вийти, сплатити за проїзд, ми заздалегідь впевнені в тому, що це можна зробити з кожним з об’єктів цього типу. Коли ми в незнайомому місті хочемо сходити в кафе, ми запитуємо у друзів або в інтернеті: «де в місті Н можна смачно поїсти?», тобто ми не визначаємо конкретний заклад, навіть його тип, а ставимо в основу найважливішу властивість групи закладів: ми можемо прийти туди та замовити їжу.

Іншими словами, у деяких ситуаціях нам важливий не об’єкт конкретного типу, а певні його властивості: тобто, що ми можемо з ним робити. Часто шуканими властивостями володіють кілька типів даних, і всі вони нам так чи інакше підійдуть, як описані вище приклади. Це призводить до визначення абстрактного типу даних. Спочатку наведемо формальне визначення, а потім розкриємо його у більш простих термінах.

Абстрактний тип даних (АТД)  – це математична модель для типів даних, де тип даних визначається поведінкою (семантикою) з точки зору користувача даних, а саме в термінах можливих значень, можливих операцій над даними цього типу та поведінки цих операцій.

Що таке математична модель? Хто такий користувач даних? Що мають на увазі під поведінкою операцій? Навіщо взагалі так ускладнювати? Давайте розумітися.

Заглиблюємося в деталі та розбираємо приклади

Щоб не перевантажувати себе новою інформацією, давайте будемо під математичною моделлю об’єкта або явища розуміти просто його формальний опис. Повертаючись, наприклад, з мамою, якій знадобилася ручка, ми можемо переробити її прохання в такий спосіб: «Сину, принеси мені, будь ласка, якийсь інструмент, який може залишати контрастні сліди на папері і при цьому поміщається до мене в руку». Звучить на побутовому рівні досить абсурдно, але саме це і буде формальним описом того, що знадобилося мамі.

Рухаємось далі. Уявімо програміста, перед яким стоїть завдання створення системи електронної черги в травмпункті.

При надходженні до травмпункту людині видається талон з номером (порядковим номером відвідувача травмпункту) та визначається пріоритетність черги: його травма оцінюється за шкалою від 1 до 10, де 10 – травма, яка потребує негайної медичної допомоги. Необхідно реалізувати механізм додавання людини до черги та визначення наступного пацієнта на прийом.

Для вирішення такого завдання потрібно створити програму, яка використовуватиме в коді деякі дані: номери талонів та їх пріоритети. У коді програми будуть проводитись операції над даними. Як ви побачите далі, ці операції не завжди прості, а можуть містити в собі безліч дій, а також мати деякі наслідки для всієї програми і всіх даних, що зберігаються: важкий пацієнт посуне всю чергу назад, тому що йому потрібна термінова медична допомога. Все в сукупності: набори операцій, дії, з яких вони складаються, а також їх наслідки називаються поведінкою операції.

Під користувачем даних ми в цій статті розумітимемо програміста, який використовує ці типи даних у своєму коді.

Залишається найважливіше питання: навіщо все це потрібне? Щоб відповісти на нього, розглянемо завдання докладніше.

Уявимо, що у черзі вже є талони з номерами 109, 101, 105, 112 з пріоритетами 5, 3, 1, 1 відповідно. Наступному пацієнту видається талон 113 з пріоритетом 3. Тоді цей талон «обходить» номери 105 і 112, тому що їхній пріоритет нижче, і встає позаду талона 101, з яким їх пріоритети рівні (мал. 1). Коли лікар готовий прийняти наступного пацієнта, то буде викликано пацієнта з номером 109 (мал. 2).

Новий пацієнт у черзі
Мал. 1. Новий пацієнт у черзі. 
Вибір наступного пацієнта у черзі.
Мал.2. Вибір наступного пацієнта у черзі.

Давайте напишемо код, який реалізує цю логіку. Будемо використовувати мову javascript . Спочатку опишемо звичайну чергу, без урахування пріоритету. Створимо клас PriorityQueue. Об’єкти цього класу міститимуть спочатку порожній масив data(створюється в конструкторі). Функція add_elemдодаватиме переданий їй параметр – номер талона – в кінець масиву data, а функція get_nextописуватиме виклик лікарем пацієнта на прийом: повертати значення першого елемента в масиві – номер пацієнта, який встав у чергу раніше за всіх інших, видаляючи з масиву цей елемент, так як , вирушаючи прийом, пацієнт залишає чергу. Також визначимо функцію print_que, яка виводитиме в консоль усі елементи черги по порядку.

class PriorityQueueconstructor(){ this.data = []; }

  add_elem(e){ this.data.push(e); }

  get_next() { return this.data.shift() }

  print_queue() {
      for(var i in this.data)	
          console.log(this.data[i]);  
  }
};

Наведемо приклад використання цього класу у коді програми:

Q = new PriorityQueue();
Q.add_elem(105);
Q.add_elem(101);
Q.add_elem(109);

console.log("next:",Q.get_next()) // next: 105
console.log("remains:") 
Q.print_queue(); // 101 109

Давайте модифікуємо клас, що вийшов, щоб черга враховувала пріоритет елемента. Для цього будемо в масиві dataзберігати не просто переданий елемент, а об’єкт із двома полями: значення ( value) та пріоритет ( priority). У коді такий об’єкт задаватиметься виразом виду var obj = {‘priority’: 1, ‘value’: 112};Перепишемо функцію додавання елемента в чергу:


add_elem(e,p)  {		
    
  for (var i = this.data.length - 1; i >= 0; i--) {		
 
    if(this.data[i].priority >= p){                
 		     
      this.data.splice(i+1,0,{'value':e, 'priority':p});                
      return;            
    }     
  }
     
  this.data.splice(0,0,{'value':e, 'priority':p});  
}

Змоделюємо ситуацію, проілюстровану малюнками 1 і 2.

Q = new PriorityQueue();
Q.add_elem(109,5);
Q.add_elem(101,3);
Q.add_elem(105,1);
Q.add_elem(112,1);
Q.add_elem(113,3);

console.log("next:",Q.get_next()) // next: { value: 109, priority: 5 }
console.log("remains:")
Q.print_queue(); // value: 101, priority: 3 }
                 //{ value: 113, priority: 3 }
                 //{ value: 105, priority: 1 }
                 //{ value: 112, priority: 1 }

Можлива модифікація: якщо пацієнт перебуває в черзі протягом тривалого часу, наприклад, за цей час лікар уже прийняв як мінімум одного пацієнта з черги, то пріоритет його талона підвищується на 1, проте не може перевищити 8, щоб залишити можливість термінового прийому важких хворих.

Для цього змінимо функцію вибору наступного елемента get_next.

get_next() {       	
  var e = this.data.shift();	
  for(var i in this.data){ 
    	
    if(this.data[i].priority<8) 
      this.data[i].priority++; 
  }	
  return e; 
}

Можемо помітити, що в даному випадку при вилученні елемента з черги змінюються всі елементи. Це і буде та сама «поведінка операції», про яку йшлося раніше.

Код програми, що вийшов, можна умовно розділити на дві частини: опис класу PriorityQueue і використання цього класу. Зауважимо, що використання класу виглядає досить лаконічно, порівняно з його описом. Працюючи з класом та її функціями програміст, який виступає у разі як користувач класу, може мати уявлення, як саме реалізована логіка роботи всередині функцій класу. Для його роботи достатньо того, що ця логіка відповідає заявленому опису пріоритетної черги. У такому разі кажуть, що клас реалізує певний інтерфейс  – набір методів роботи з класом, де зафіксовано вхідні та вихідні параметри. У цьому прикладі це методи add_elemget_next і print_queue. Можна змінити внутрішню логіку роботи цих методів, якщо цього вимагатиме завдання, як це було у разі підвищення пріоритету при довгому очікуванні. Однак для користувача класу ці зміни не будуть помітними і не вимагатимуть зміни коду основної програми.

Бонус. Що таке структура даних?

У програмуванні також є поняття структури даних, яке певною мірою близьке за змістом типу даних.

У чому різниця? Структура даних – це конкретна програмна реалізація типу даних. Якщо двох людей попросити реалізувати пріоритетну чергу, швидше за все навіть при використанні однієї мови програмування їх реалізації відрізнятимуться, хоча обидві відповідатимуть заявленому інтерфейсу. Тобто вони створять дві різні структури даних.

Структура даних (англ. data structure) — програмна одиниця, що дозволяє зберігати та обробляти безліч однотипних та/або логічно пов’язаних даних у обчислювальній техніці. Для додавання, пошуку, зміни та видалення даних структура даних надає деякий набір функцій, що становлять її інтерфейс.

Висновок

Підіб’ємо підсумки виконаної роботи. Клас PriorityQueueмає такі властивості:

  1. Він може зберігати у собі будь-які елементи з пріоритетом, який задається числом.
  2. Визначено інтерфейс взаємодії з класом: методи add_elemget_nextі print_queue.
  3. Описані методи реалізують заявлену логіку роботи пріоритетної черги.
  4. Методи мають певну поведінку (див., наприклад, бонус).

Таким чином, ми створили свій абстрактний тип даних та реалізували його мовою javascript . Що ми від цього виграли:

  1. Код основної програми лаконічний і зрозумілий, тому що не містить технічних подробиць внутрішньої роботи черги.
  2. Зручно вносити зміни до логіки роботи черги, не торкаючись основного коду.
  3. Клас PriorityQueueможе бути перевикористаний в інших програмах, де потрібна схожа логіка.
  4. У разі командної роботи можна поділити між людьми роботу над класом та розробку з використанням цього класу. Сполучною ланкою буде інтерфейс класу.

Незважаючи на те, що розробка абстрактного типу даних сама по собі може бути досить трудомісткою, використання АТД здорово допомагає заощадити сили і час при роботі зі складними завданнями. Принцип «розділяй і владарюй» працює тут якнайкраще: створення додаткового рівня абстракції допомагає розробнику розбити складне завдання на дрібніші і простіші, а його колегам спрощує розуміння коду програми, що надзвичайно важливо в командній розробці.

Звичайно, АТД – це не панацея, яка допоможе зробити будь-який код прекрасним, читаним і зрозумілим, уникнувши всіх помилок. Дуже часто навіть досвідчені програмісти у своєму прагненні зробити все правильно та красиво заходять надто далеко в нетрі абстракцій, що навпаки все ускладнює. Коли варто створювати нову абстракцію, а коли це зайве, зрозуміти можна лише з досвідом. Універсального рецепта немає, можна лише порадити намагатися періодично переглядати свій старий код, щоб зробити висновки, що з написаного робить його зрозумілішим, а що через деякий час незрозуміло вже навіть вам самим.

Пам’ятайте, що у висловлювання Девіда Віллера і є і друга, менш відома частина:

У комп’ютерній науці всі проблеми можна вирішити з допомогою додаткового рівня непрямості. Але зазвичай це створює іншу проблему

Джерело