Предыдущий пост Поделиться Следующий пост
Теологическое программирование
lex_kravetski
Этот рассказ написан в совершенно новом, неизведанном и оригинальном жанре — повествование в коде.

Уверен, в будущем этот жанр овладеет умами, однако сейчас он может отпугнуть новизной подхода.

Кроме того, в рассказе речь идёт ещё и о всяких там теологических вопросах, поэтому от читателя потребуется не только понимание языков программирования, но ещё и знание нюансов христианских религий.

Вдобавок весь текст на английском языке, хотя и не на очень сложном. Это ещё один фактор, затрудняющий чтение — по крайней мере, для большинства русскоязычной аудитории.

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

Вперёд, читатель. Вперёд в неизведанное.


trait Person {
     val isMale: Boolean
}

trait Male extends Person {
     val isMale: Boolean = true
}

trait Female extends Person {
     val isMale: Boolean = false
}

trait Parent extends Person {
     val children: List[Child]
}

trait Child extends Person {
     val parents: List[Parent]
}

trait Father extends Parent with Male

trait Mother extends Parent with Female

trait Son extends Child with Male

trait Holy {
     val proceedsHolySpirit: Boolean
}

trait HolySpirit extends Holy {
     override val proceedsHolySpirit = false
}

trait HolySon extends Son with Holy {
     // I really tried to implement it in this way, but, you see later, it's impossible.
     // val parents = List(God, Mary)
}

trait HolyFather extends Father with Holy {
     val proceedsHolySpirit = true
}

trait CatholicHolyFather extends HolyFather {

     // TODO: Is he really need to be child of himself?
     val children = List(CatholicGod)
}

trait OrthodoxHolyFather extends HolyFather {
     val children = List(OrthodoxGod)
}

// TODO: He is not the father of Christ technically. Do we really need to mention him?
object FakeFather extends Father with Holy {

     // TODO: Had Joseph other children? From previous marriage, I don't know, or so?
     // TODO: There is symmetry violation with Holy Son's parents here. It may be a problem.
     val children = List()

     val proceedsHolySpirit: Boolean = false
}

trait Mary extends Mother with Holy {
     val proceedsHolySpirit = false
}

// TODO: Jesus Christ! You should have only one mother. But…
object CatholicMary extends Mary {
     val children = List(CatholicGod)
}

object OrthodoxMary extends Mary {
     val children = List(OrthodoxGod)
}

trait CatholicHolySon extends HolySon {

     // TODO: How many parents He has? Should we believe in 3 of them?
     // TODO: Or, maybe, we need another list for fake parents?
     val parents = List(CatholicGod, CatholicMary, FakeFather)

     // That's the case, which broke the party.
     override val proceedsHolySpirit = true
}

// TODO: Jesus! Now we have two copy of you too.
// TODO: And you are trait now, not the object, because the God is the object.
trait OrthodoxHolySon extends HolySon {
     val parents = List(OrthodoxGod, OrthodoxMary, FakeFather)

     override val proceedsHolySpirit = false
}

object CatholicGod extends God with CatholicHolySon with CatholicHolyFather

// TODO: It needs to be only one singleton. It is the Christian law, after all.
// Please, forgive me. But it was not me, who's done it in real world.
object OrthodoxGod extends God with OrthodoxHolyFather with OrthodoxHolySon {

     // TODO: Otherwise OrthodoxHolySon value overrides OrthodoxHolyFather value.
     // TODO: But HolySons are traits, not objects.
     // TODO: So, who does not proceed HolySpirit in this case?
     // TODO: Probably, we should use ChristianBoolean instead.
     override val proceedsHolySpirit: Boolean = true
}

trait God extends HolyFather with HolySon with HolySpirit {

     // TODO: Oh, yes. We have several singletons, which all are the only one.
     val isTheOnlyOne = true

     // TODO: It is very hard to make it works. Some helper is needed.
     // Please, God, help me.
     override def equals(obj: Any) = christianEquals(obj).boolValue

     def christianEquals(obj: Any) = {
         obj match {
              case _: this.type => ChristianReallyTrue

              // The other God case. Forgive me, The God.
              // It doesn't work with normal booleans. I've tried.
              case _: God => 
                  !ChristianTrue && !ChristianFalse && 
                        ChristianTrue && ChristianFalse

              case _ => ChristianReallyFalse
         }
     }
}

object ChristianTrue extends ChristianBoolean

object ChristianFalse extends ChristianBoolean

object ChristianReallyTrue extends ChristianBoolean {
     override def boolValue = true

     // TODO: That's the two rules, I can understand. But I'm not sure.
     override def unary_! = ChristianReallyFalse
}

object ChristianReallyFalse extends ChristianBoolean {
     override def boolValue = false

     // TODO: Here is the second one.
     override def unary_! = ChristianReallyTrue
}

// TODO: Please, God, help me to make this less abstract.
abstract class ChristianBoolean {

     // TODO: Oh, Christ! How it should work not for ChristianReallyTrue and ChristianReallyFalse?
     def unary_! = thatsTheLogic(this)

     // TODO: You can't understand this, can you?
     def ==(x: ChristianBoolean) = thatsTheLogic(x)

     // TODO: I am too. But I've found the Way. This is the Way. Yes. The Way.
     def !=(x: ChristianBoolean) = thatsTheLogic(x)

     // TODO: Should I do it. Why I do it?
     def ||(x: ChristianBoolean) = thatsTheLogic(x)

     // TODO: Because fuck, that's why!
     def &&(x: ChristianBoolean) = thatsTheLogic(x)

     // TODO: Now you know, how it works.
     def thatsTheLogic(x: ChristianBoolean): ChristianBoolean =
         Random.nextBoolean() match {
              case true => ChristianTrue
              case false => ChristianFalse
         }

     // TODO: Welcome to the real world, motherfuckers.
     def boolValue: Boolean = Random.nextBoolean()
}




doc-файл


  • 1
Несколько замечаний

1) А зачем proceedsHolySpirit? Нельзя трейтом тоже сделать?

2)

object CatholicMary extends Mary {
val children = List(CatholicGod)
}

object OrthodoxMary extends Mary {
val children = List(OrthodoxGod)
}

Да? А почему не List(<...>HolySon)? И вообще тут бы обобщить, и добавить детей сразу к Mary, а направление христианства специлизировать через темплейт :)

В общем, идея хорошая, но надо бы еще поработать немного. Хотя бы 7 дней :)

> 1) А зачем proceedsHolySpirit? Нельзя трейтом тоже сделать?

Он уже. Это — единственный метод трейта Holy. Нужный, чтобы различать степени святости. Что потом оказывается критично для двух версий бога.


> А почему не List(<...>HolySon)?

На Scala так можно. Уже ранее заявлено, что children — это List[Child]. Дальше, при имплементациях и оверрайдах, тип можно не указывать.

Если же вопрос про то, почему в списке HolySon, так это — трейт. Там только бог получается объектом, что доставляет баттхерт лирическому герою. Но бог по наследованию ещё и экземпляр HolySon, просто Son и Child, поэтому фокус прокатывает.

Через дженерик тоже можно, но читать будет тяжело — там весьма длинное определение классов получится.

Божественные задачи требуют божественных плюсов:

auto main (auto, auto) NORETURN
{
while (1) auto ();
}

И всё.

Боян же ж!



И ещё до кучи немного о любви:


[Love.cpp], Автор: Лев Артурович Ткаченко

#include
[Error: Irreparable invalid markup ('<god.h>') in entry. Owner must fix manually. Raw contents below.]

Боян же ж!

<img src="https://habrastorage.org/storage2/8b8/3d8/572/8b83d8572aacd9795d16c14792e0506a.png">

И ещё до кучи немного о любви:


[Love.cpp], Автор: Лев Артурович Ткаченко

#include <God.h>
#include <Time.h>
#include <Love.h>
#include <persones\LonelyLion.obj>
#include <persones\She.obj>
// -----------------------------
#define is ==
// -----------------------------
begin:
// -----------------------------


if( Time() is EVENING ) {close(ALL_THE_STREAMING);
( shutdown(NULL) AND finished(ALL_PROCESS)) }
else {(close(EYES); start((float *)function Dreaming())
AND (see(Her->Body->Lips->Legs[i + next])); }

God->allocated(many_happy_seconds);
for(Me + You) {FOREVER_BE_INLOVE};
stop(RAIN); repeat { play(sound());} until(dancing());
#ifNotDefined EventExit (int) 1;

while (NOT say("YES")) repeat{1} until(waiting());
if(_say_ is TRUE) {( MyHeart(ONLINE); Volume();
Sky(ON_SUNSET); increasing(Brightness_Rating); )
AND (Date is new(*struct ParadiseForYou)) }

putstring(1,1, "Hello,world! I LOVE YOU!!!");
getch(); DRAW_SMILE(MAGENTA_COLOR, screen);
compile(My_And_Her_Life, InGodsDebugger)
AND {close(file); save(); goto begin;}

Я статью, конечно, не читал.
Однако сразу задам вопрос строго по теме: Лекс, а ты еврей?

Вот это твоё "думаю, нет" рождает неоднозначность, которая мешает однозначно оценить теологическую часть.
Ну, а в программировании я вообще не бум-бум.

Сильно.

OrthodoxGod: override val proceedsHolySpirit: Boolean = true ← Это так и надо?

На christianEquals я потерялся. Ну, то есть, идею ChristianBoolean я понял, а вот ту конструкцию — нет.

> OrthodoxGod: override val proceedsHolySpirit: Boolean = true ← Это так и надо?

Да. В этом одна из разниц межу католицизмом и православием.

> На christianEquals я потерялся. Ну, то есть, идею ChristianBoolean я понял, а вот ту конструкцию — нет.

А этом самая сатира. Надо ещё поразбираться.

Код за разум заходит.
И сказал Господь на 6-й день, оглядывая плоды рук своех:
Заебись!
И оне заеблись.

Edited at 2018-06-06 19:49 (UTC)

слишком много дублирования кода вокруг proceedsHolySpirit. Надо было сделать CatholicHolySpirit и OrthodoxHolySpirit, и передавать его в качестве параметра в конструкторы God, Son и т.п.
И родителей надо не список, а пару, точнее две пары: formalParents и realParents.

> слишком много дублирования кода вокруг proceedsHolySpirit. Надо было сделать CatholicHolySpirit и OrthodoxHolySpirit, и передавать его в качестве параметра в конструкторы God, Son и т.п.

Так будет менее лаконично.


> И родителей надо не список, а пару, точнее две пары: formalParents и realParents.

Это опционально. Лирический герой уже думает об этом.

И еще. Извините, что на эльфийском, но думаю лирический герой меня поймет:

public interface Alive {
Date getBirthDate();
}

public interface Dead extends Alive {
Date getDeathDate();
}

public interface Zombie extends Dead {
Date getRessurectionDate();
}

И дальше
public class HolySon extends Son implements Zombie, Holy

Прошу прощения а почему trait, а не class?
Это Scala?

Scala, да. trait потому, что надо заявить поля (хотя в Scala это по сути тоже методы), но им невозможно приписать значение на этом этапе. Можно было бы сделать abstract class, однако от них сейчас в Scala нет множественного наследования.

А может объявить Марию суррогатной матерью?

  • 1
?

Log in

No account? Create an account