Что за язык программирования ДНК?

Проводя исследование для другой статьи, я сначала подумал, что сходство между ДНК и кодом было поверхностным, а термин «генетический код» — скорее образным способом выражения отношения.

Есть, конечно, различия, компьютеры используют электроны в качестве среды передачи информации, а ДНК использует молекулы. ДНК и связанные с ней ферменты больше похожи на химическую программу, чем на электрическую. Репликация ДНК занимает гораздо больше времени, чем любое программное обеспечение, перебирающее список.

Хромосома человека среднего размера содержит одну линейную молекулу ДНК из примерно 150 миллионов пар нуклеотидов. Для репликации такой молекулы ДНК из конца в конец с помощью одной репликационной вилки, движущейся со скоростью 50 нуклеотидов в секунду, потребуется 0,02 × 150 × 106 = 3,0 × 106 секунд (около 800 часов).

Однако слишком много сверхъестественных сходств заставляют меня задаться вопросом, откуда на самом деле взялась ДНК. Кто мог его спроектировать и какова была первоначальная цель?

Основания ДНК и числа с основанием 4

Первое сходство в основаниях. ДНК состоит из четырех оснований: цитозина [C], гуанина [G], аденина [A] и тимина [T]. Это аминокислоты с различным химическим составом, который их отличает. Они образуют систему счисления с основанием 4, которая может представлять различные значения. Цифровые компьютеры, с другой стороны, используют двоичную систему с основанием 2 только с двумя цифрами, 1 и 0, или включают и выключают. Хотя это может показаться другим, основание 2 всего лишь кратно 2 от основания 4. Цифровой единицей двоичного кода является бит; восемь битов сгруппированы вместе, чтобы сформировать байт.

Преобразование между двоичной системой и системой счисления по основанию 4 очень просто. Мы можем сгруппировать двоичные числа в группы по два и легко преобразовать их в основание 4. Например, двоичное число 1011 (11 в десятичной системе) при группировании становится (10)(11), которое затем мы можем переписать по основанию 4 как 23, если мы свяжем каждое основание ДНК с числом по основанию 4 следующим образом: C — 0, G — 1, A — 2, T — 3, то мы можем получить строку кода ДНК. В нашем примере это будет AT.

Слова, кодоны и машинный код

Компьютеры на базовом уровне используют тип языка, называемый машинным кодом. Машинный код — это числовой код, который процессор интерпретирует как инструкции, сообщающие процессору, что делать. Эти инструкции машинного кода обычно записываются в шестнадцатеричной системе счисления с основанием 16. Например, для процессора Intel x86 команда MOV, перемещающая данные из одной ячейки памяти в другую, использует инструкцию машинного кода 0xA0 или 160 в десятичном виде. Ассемблирование — это еще один вид кода, который компилируется в машинный код и имеет похожие наборы инструкций.

Память сгруппирована в слова, которые представляют собой серию байтов; на большинстве процессоров размер слова составляет 4 байта, что в сумме составляет 32 бита. Память обычно можно прочитать только по размеру слова или как-то нарезать на его основе. Это как наименьшая единица памяти, с которой можно работать на компьютере.

В ДНК тоже есть что-то вроде слова; в ДНК это кодон, представляющий собой группу из трех оснований. Такой кодон, как GAC, означает, что в молекуле присутствуют гуанин, аденин и цитозин. Кодоны важны, потому что они описывают, как строить более поздние белки, которые нужны нам как биологическим организмам. Эти кодоны создают аминокислоты во время трансляции, а химические свойства аминокислот заставляют их складываться определенным образом для образования белков. Это похоже на белковое оригами, где белки складываются в сложные формы.

Кроме того, существуют регуляторные области, в которых ДНК можно включать и выключать, например директива условной компиляции в C, которая может определять, какой код компилируется, а какой нет.

Составление генетического кода с помощью РНК

Каждый кодон инструктирует информационную РНК (мРНК), которая затем конструирует ассоциированный белок. В биологии это называется центральной догмой; ДНК служит программой, РНК — мессенджером, а белок — продуктом. РНК отличается от ДНК тем, что она имеет другие основания и скорее реактивна, чем нереактивна. Это означает, что он может взаимодействовать с другими молекулами, что делает его важным для создания белков. РНК также имеет разные основания, которые сопоставляются с основанием ДНК. Аденин [A], цитозин [C], урацил [U] и гуанин [G].

ДНК сопоставляется с информационной РНК в процессе, называемом транскрипцией. В этом процессе фермент под названием РНК-полимераза, представляющий собой небольшой белок, способный выполнять вычислительные операции, перемещается по длине молекулы ДНК и транслирует ее в РНК основание за основанием. Например, кодон ДНК ATC транскрибируется в UAG.

Точно так же и в программном обеспечении у нас есть эквивалентная аналогия. То, что я сказал ранее, не совсем верно; однако ДНК больше похожа на программный код языка более высокого уровня. Это удобочитаемо и может быть легко прочитано людьми. Это может быть ассемблер, а может быть, например, такой язык, как C. Программа на C будет скомпилирована в машинный код с помощью компилятора. Некомпилированный код нереактивен, как и ДНК; он ничего не может сделать и сидит на жестком диске, занимая место.

Давайте возьмем язык ассемблера в качестве сравнения с ДНК. Сборка собирается с помощью ассемблера, программы, которая отображает каждую инструкцию сборки в инструкцию машинного кода. Например, следующий ассемблерный код.

mov $2, %a
add $3, %a

Переместит число 2 в регистр a, который является ячейкой памяти процессора. Это будет переведено в машинный код через ассемблер путем прямого перевода каждой ассемблерной инструкции. Предыдущая сборка будет преобразована в машинный код.

A300000000010500000000

Посмотрите, как это чем-то напоминает цепочку РНК. Каждая ассемблерная инструкция сопоставляется с новой инструкцией машинного кода. Всего имеется 64 кодона, что, как ни странно, соответствует размеру большинства целых чисел на новых процессорах. Большинство процессоров сегодня используют 64 бита для описания чисел, таких как целые и десятичные числа.

Старт и стоп кодон

Некоторые кодоны служат для запуска или выхода из генетической программы. Это так называемые стартовые и стоп-кодоны. Стартовый кодон AUG в мРНК запускает новый белок. Стоп-кодон останавливает фермент от создания нового белка; это как выход. Есть несколько стоп-кодонов, таких как UUA или UAG, которые останавливают транскрипцию и синтез нового белка.

Как мы можем интерпретировать это в вычислительном контексте? В ассемблере есть такие инструкции, как exit или ret, которые либо завершают работу программы, либо возвращаются из подпрограммы. Это означает, что выполнение программы остановится и вернется к какой-то другой программе. Другой пример — HTML/XML и JSX. В этих форматах описания данных и веб-страниц начальный тег указывает, где начинаются данные, а конечный тег указывает, где они заканчиваются. Например, XML для описания белка может выглядеть так.

<protein type="mRNA">
  <codon>AGU</codon>
  <codon>UAC</codon>
    ...
</protein>

Где тег «белок» заменен стартовым кодоном, а тег «/белок» заменен стоп-кодоном. Затем кодоны между ними указывают на структуру белка. На самом деле, XML — отличный способ походить на белки в мРНК.

Генетическое программирование

Такие технологии, как CRISPR, позволяют сравнительно легко сплайсировать гены. Поскольку гены можно соединять по желанию, возможно, есть способ сделать это на текстовом языке программирования. Такие языки уже есть, типа разработанных в MIT. Они представляют интерес, поскольку могут описывать биологические цепи.

Если бы нам нужно было создать язык генетического программирования, что-то вроде XML могло бы быть выгоднее, поскольку представления очень похожи. Другой возможностью может быть язык, подобный ассемблеру; однако у ДНК/РНК нет эквивалентного фермента, имитирующего процессор, поэтому аналогия не столь уместна.

Каким языком являются ДНК и мРНК?

Напрашивается вопрос, какой парадигмой языка программирования является ДНК? Давайте обобщим различные типы парадигм программирования.

  • Императив. В императиве код организован в блоки, называемые подпрограммами или процедурами. Блоки кода выполняются вместе и запускаются последовательно один за другим. После завершения выполнения одного оператора запускается следующий. Алгоритмы описываются в императивной манере, в которой шаги должны выполняться. Именно так запускаются машинный код, ассемблер, C, Java, Javascript, Python и т. д.
  • Декларативный. В этой парадигме код выражает то, что мы хотим видеть или иметь. Он описывает данные и внешний вид, а не описывает алгоритм их создания. Это предпочтительный метод для описания визуальных элементов или описания данных. Примером может служить SQL, SVG, HTML, LATEX или XML.
  • Объектно-ориентированный — в этой парадигме код представляет объекты и классы. Они представляют собой реальные физические субстраты. Например, объект может представлять автомобиль с его колесами, трансмиссией, мотором и т. д. Примерами объектно-ориентированных языков являются Java, Ruby и Smalltalk.
  • Функциональный — в этой парадигме код представлен в виде математического выражения с неизменяемыми значениями. Например, функция может представлять функцию синуса или квадратный корень. Поскольку код не представляет собой последовательное выполнение, необходимо использовать модель, которая эмулирует его при работе с вводом и выводом, например, побочные эффекты, монады и т. д. Примерами являются Haskell, Javascript и Lisp.
  • Логический — в логических языках, таких как Prolog, код представляет собой логические операторы, которые можно вычислить, и результирующее выражение является логическим. Оцениваются силлогизмы и другие логические выражения, и возвращается результат. Например, утверждение «если идет дождь, то Эбби и Бетти пойдут в церковь» является логическим утверждением, которое можно выразить как его эквивалент на логическом языке.

Поскольку ДНК представлена ​​серией оснований, сгруппированных в кодоны, она затем компилируется в мРНК, а затем транслируется в аминокислоты, из которых формируются белки. Сначала мы можем подумать, что это необходимо, поскольку существуют такие инструкции, как стартовые и стоп-кодоны. Однако большинство кодонов не обязательно представляют собой инструкции для какого-либо интерпретатора или процессора. Вместо этого они описывают, как белок должен сворачиваться и какие аминокислоты использовать. Звучит знакомо? Это то, как работают HTML и XML и такие технологии, как React с JSX. JSX — это просто XML в коде Javascript, который можно использовать для описания веб-браузеру того, что показывать на веб-странице.

Белки складываются в определенные формы, определяемые составляющими их аминокислотами. Эти формы, такие как альфа-спирали и бета-листы, определяются химическим составом аминокислот и структурой аминокислотных оснований. Поскольку мРНК описывает, где должны происходить складки белка, это декларативный язык, подобный XML. Он также может быть представлен на императивном языке, но ни один процессор не может точно выполнять команды. Сворачивание происходит само по себе из-за химических свойств белка. Точно так же ДНК была бы декларативным языком, потому что она напрямую транскрибируется в мРНК.

На что будет похожа фаза транскрипции ДНК на мРНК в вычислительном контексте? Возможно, этап компиляции в React from JSX to Javascript+HTML using babel. Babel — это транскомпилятор, который компилирует JSX в простой Javascript с динамически добавляемыми элементами HTML. Другим примером может быть что-то вроде компилятора Markdown to HTML, который преобразует команду Markdown, например #, в HTML-тег, например ‹h1›.

Почему я выбрал декларативный язык, а не императивный, и описал ДНК/мРНК как декларативный язык? Сначала я думал, что это обязательно, но ДНК не описывает, что должно выполняться, какая команда за другой; он просто описывает, как белок должен сворачиваться. Именно эта укладка описывает функциональность белка. Это язык описания данных, а не прямой язык программирования. Это описывает внешний вид белка в дополнение к его функциональности.

Кроме того, нет ферментного эквивалента процессора. Ферменты-полимеразы похожи, но они просто прославленные конечные автоматы или преобразователи. Они не так уж сильно отличаются от ассемблера или транспилятора. На самом деле транспиляция является лучшей аналогией, чем компиляция того, что фермент РНК-полимераза делает во время транскрипции. Другими подобными аналогиями могут быть транспиляторы, конвертирующие SASS в CSS. Это также кодирует визуальные и структурные компоненты.

Вот почему я описал мРНК как HTML; он также реактивен, как HTML, поскольку может взаимодействовать с другими молекулами мРНК, как HTML на сервере. Почему XML лучше других декларативных языков? У Markdown нет понятия, которое переводится в стартовые и стоп-кодоны. В JSON есть понятие скобок, например {белок: ["UAG"]}, но они должны описывать объект с помощью метки и не дают никакого представления ни о назначении белка, ни о понятии стоп-кодона. Теги в XML являются лучшим представлением стартовых и стоп-кодонов, например тег «белок».

Другим возможным представлением может быть SVG, XML-представление масштабируемой векторной графики. Это описывает 2D-графику, а поскольку белковые складки имеют трехмерное представление, то 3D-формат, такой как Collada, может быть лучшей аналогией. Однажды у нас может быть компилятор мРНК, который компилирует что-то вроде XML в образец мРНК.

Разработка языка ДНК

Если бы мне пришлось разработать язык программирования, максимально похожий на ДНК и максимально эквивалентный в вычислительном отношении, он выглядел бы примерно так.

<gene name="HsARG1">
  <start seq="ATG">
    <codon>ATC</codon>
    <codon>GCT</codon>
    ...
  <stop seq="TAG">
</gene>

Если по стечению обстоятельств последовательность ДНК стоп-кодона мРНК UAG представляет собой TAG.

Отношение к Гермесу

Если вы действительно хотите трахнуть мозги, нам нужно немного изучить греческую мифологию. В романо-греческой мифологии бог Гермес — посланник, олимпийский бог, который переправляет сообщения туда и обратно между богами и смертными. Теперь символом Гермеса является кадуцей или жезл Гермеса. Посох выглядит идентично двойной спирали ДНК, и когда ДНК транскрибируется, она становится мРНК или матричной РНК.

Таким образом, символика говорит нам, что Гермес — это тот, кто некоторым образом опосредует синтез ДНК/РНК для людей и, возможно, для других видов. Говорит ли это нам, что Гермес — генный инженер? Я не знаю, но это кажется возможным и даже вероятным, если моя интерпретация символики верна. Древние греки не имели прямого представления о современной генетике, но, возможно, они пытались показать, что это сделали боги, и именно это и сделали некоторые боги, такие как Гермес. В любом случае, это все, ДНК сейчас интересна.