WEBVTT

00:00:00.000 --> 00:00:04.100
Ja, hallo, liebe Hörerinnen und Hörer, willkommen beim Python-Podcast, heute Episode 54.

00:00:04.820 --> 00:00:07.320
Wir reden heute über Types, Typings und Typescript.

00:00:08.100 --> 00:00:08.420
Hallihallo.

00:00:08.760 --> 00:00:10.980
Hallihallo, willkommen Dominik und...

00:00:10.980 --> 00:00:11.500
Hallo Johannes.

00:00:11.620 --> 00:00:12.140
Hallo Johannes.

00:00:12.560 --> 00:00:13.180
Hallo zusammen.

00:00:13.640 --> 00:00:14.320
Und hallo Stefan.

00:00:14.820 --> 00:00:15.140
Genau.

00:00:15.440 --> 00:00:16.040
Ja, hallo Stefan.

00:00:16.600 --> 00:00:17.660
Auch ein Gast heute.

00:00:17.860 --> 00:00:18.040
Genau.

00:00:18.820 --> 00:00:23.820
Ja, wir freuen uns sehr, dass ihr alle da seid und fangen einfach mit News an, wie sonst auch immer.

00:00:24.220 --> 00:00:25.600
Ja, würde ich schon sagen.

00:00:25.800 --> 00:00:26.560
Was gab es denn Schönes?

00:00:27.360 --> 00:00:28.400
Wer möchte anfangen, soll ich?

00:00:28.660 --> 00:00:29.260
Ja, fang du mal an.

00:00:29.540 --> 00:00:34.820
Na gut, ja, also ehrlich gesagt, das letzte Mal war nicht so lange her, daher habe ich ja nicht so viel gesammelt.

00:00:34.940 --> 00:00:35.780
Heißt ein 3.12.1.

00:00:36.460 --> 00:00:50.680
Genau, das ist natürlich irgendwie, es stand irgendwie dabei, so 400 Bugfixes und so, also sollte man wahrscheinlich mal installieren und meine Frage dazu wäre halt, bist du jetzt schon umgestiegen auf 3.12, weil du wolltest ja immer nur die erste meiner Version abwarten, aber dann auch, ja?

00:00:50.680 --> 00:00:52.720
Ja, also noch nicht mit allen Sachen, aber

00:00:52.720 --> 00:00:53.540
mit vielen Sachen.

00:00:54.320 --> 00:00:56.700
Also 3.12, das ist bei 1 draufgekommen und

00:00:56.700 --> 00:00:58.660
jetzt in meinem Systeminterpreter

00:00:58.660 --> 00:00:59.720
zum Beispiel ist das auf 3.12.

00:01:00.960 --> 00:01:02.800
Hervorragend. Tja, aber ich glaube

00:01:02.800 --> 00:01:04.580
da war nichts,

00:01:04.740 --> 00:01:06.480
also außer Bugs ist da nichts irgendwie

00:01:06.480 --> 00:01:08.580
passiert. Mein Hauptproblem im Moment

00:01:08.580 --> 00:01:10.580
ist halt PyTorch oder sowas, wo es auch im

00:01:10.580 --> 00:01:12.380
Dezember einen Release gab, dass es jetzt endlich mit 3.11

00:01:12.380 --> 00:01:13.860
funktioniert. Ah, ja, ja.

00:01:13.960 --> 00:01:17.180
Ja, ansonsten

00:01:17.180 --> 00:01:18.580
genau neue Releases. Es gab

00:01:18.580 --> 00:01:20.540
neue Ruby on Rails

00:01:20.540 --> 00:01:22.500
Release. Ich gucke da ab und zu mal so

00:01:22.500 --> 00:01:24.560
rüber, weil ich halt interessant finde, wie viel

00:01:24.560 --> 00:01:26.740
tolles

00:01:26.740 --> 00:01:28.480
Zeug da passiert. Und das ist jetzt

00:01:28.480 --> 00:01:30.480
deutlich schneller geworden.

00:01:30.620 --> 00:01:32.040
Hat irgendwie einen eingebauten

00:01:32.040 --> 00:01:34.480
Time-Compiler und

00:01:34.480 --> 00:01:35.820
verwendet jetzt einen ähnlichen

00:01:35.820 --> 00:01:38.280
Ansatz für den Parser, wie

00:01:38.280 --> 00:01:39.900
Python halt auch. Python ist ja jetzt mit

00:01:39.900 --> 00:01:42.620
3.9 auf dem Pack-Parser umgestiegen.

00:01:43.920 --> 00:01:44.600
Und das

00:01:44.600 --> 00:01:46.400
ist, Ruby verwendet da jetzt was

00:01:46.400 --> 00:01:48.500
ganz ähnliches. Ist auch so ein

00:01:48.500 --> 00:01:50.280
rekursives Dings da, Parsen

00:01:50.280 --> 00:01:51.820
ich weiß nicht, ich habe es wieder vergessen, wie das

00:01:51.820 --> 00:01:54.240
genau heißt, so ähnlich. Und sie sind

00:01:54.240 --> 00:01:56.380
auch umgestiegen von Bison, also dem Pasa-Generator

00:01:56.380 --> 00:01:58.180
auf den anderen. Ich habe, finde ich, schon ganz oft

00:01:58.180 --> 00:02:00.200
Lob für Ruby gehört, muss ich ehrlich

00:02:00.200 --> 00:02:02.200
sagen. Ja, und auch bei dieser

00:02:02.200 --> 00:02:04.340
ganzen Just-in-Time-Compile-Geschichte,

00:02:05.000 --> 00:02:06.180
da ist, glaube ich, einer

00:02:06.180 --> 00:02:07.940
der Hauptsponsoren auch Shopify.

00:02:09.260 --> 00:02:09.780
Ja, genau.

00:02:10.380 --> 00:02:12.040
Also es gibt ja viele große

00:02:12.040 --> 00:02:13.940
Unternehmen, die hauptsächlich

00:02:13.940 --> 00:02:16.340
auf Ruby und Rails-Moduliten basieren

00:02:16.340 --> 00:02:18.140
und da kommt halt auch

00:02:18.140 --> 00:02:19.420
eine Menge Geld rein.

00:02:20.280 --> 00:02:22.420
und ja, Python ist ja jetzt auch

00:02:22.420 --> 00:02:24.300
dran mit diesem Just-in-Time-Compiler

00:02:24.300 --> 00:02:26.780
Thema, da in 3.13 kommt das ja auch.

00:02:26.800 --> 00:02:28.600
Das wäre meine News gewesen, Jochen. Achso, sorry.

00:02:29.880 --> 00:02:30.600
Dann schieb's mal los.

00:02:31.960 --> 00:02:32.160
Ja,

00:02:32.580 --> 00:02:34.500
Ende Dezember

00:02:34.500 --> 00:02:36.220
ist wohl ein Patch in den 3.13

00:02:36.220 --> 00:02:38.320
Branch reingekommen, wo ein JIT-Compiler

00:02:38.320 --> 00:02:40.260
drin ist für Python. Also es ist jetzt

00:02:40.260 --> 00:02:42.340
richtig im Plan drin, dass Python

00:02:42.340 --> 00:02:44.840
in 3.13 einen JIT-Compiler hat, einen Copy-and-Patch

00:02:44.840 --> 00:02:46.380
JIT-Compiler, was

00:02:46.380 --> 00:02:48.060
auch immer das bedeuten mag.

00:02:48.080 --> 00:02:50.440
Da gab es auch angeblich eine wundervolle Diskussion

00:02:50.440 --> 00:02:51.860
auf Reddit zu...

00:02:51.860 --> 00:02:54.380
Ja, also

00:02:54.380 --> 00:02:56.380
es gibt einmal die, ich kann empfehlen,

00:02:56.600 --> 00:02:58.260
es gibt Core-PY, das ist

00:02:58.260 --> 00:03:00.560
ein Podcast, wo zwei der Core-Entwickler

00:03:00.560 --> 00:03:02.300
irgendwie drüber reden. Da gibt es eine

00:03:02.300 --> 00:03:03.700
Episode zum Just-In-Time-Compiler.

00:03:04.500 --> 00:03:06.180
Und dann... Wer sind dabei?

00:03:06.340 --> 00:03:07.980
Shannon und Sean? Oder wie ist das?

00:03:08.400 --> 00:03:10.360
Nee, das

00:03:10.360 --> 00:03:12.320
sind Pablo Galindo

00:03:12.320 --> 00:03:14.460
Salgado, der Release-Manager

00:03:14.460 --> 00:03:16.460
auch für die, für 3.13.

00:03:17.740 --> 00:03:19.480
Und, äh, Lukas Schlanger.

00:03:20.120 --> 00:03:21.080
Ah ja. Genau.

00:03:21.520 --> 00:03:23.740
Und, ähm, genau, die haben da einmal drüber geredet

00:03:23.740 --> 00:03:25.660
und, äh, daher weiß ich auch,

00:03:25.760 --> 00:03:27.820
dass das, ähm, das basiert

00:03:27.820 --> 00:03:29.560
hauptsächlich, also warum man das jetzt nochmal

00:03:29.560 --> 00:03:30.760
in Angriff nimmt, auf

00:03:30.760 --> 00:03:32.900
Geschichten, die in Lua passiert sind.

00:03:33.360 --> 00:03:34.900
Da gab's jetzt auch irgendwelche,

00:03:34.960 --> 00:03:37.680
ich hab jetzt wieder die Details vergessen, aber so

00:03:37.680 --> 00:03:39.480
Papers, äh, die sehr, sehr interessant

00:03:39.480 --> 00:03:41.480
aussahen und die halt vermuten lassen,

00:03:41.540 --> 00:03:43.560
dass man's relativ leicht, äh, irgendwie auch für Python

00:03:43.560 --> 00:03:45.620
verwenden kann und, ähm, ja, das ist

00:03:45.620 --> 00:03:47.480
halt ein InPython in, in, in,

00:03:47.740 --> 00:03:49.060
Ruby, da werden überall diese

00:03:49.060 --> 00:03:49.980
Dinger jetzt gerade eingebaut.

00:03:50.920 --> 00:03:52.980
Und hier der, der wegen dem PyPy

00:03:52.980 --> 00:03:53.820
auch hier war schon,

00:03:54.800 --> 00:03:57.180
der meinte

00:03:57.180 --> 00:03:58.880
auch so, oh, er muss jetzt mal sein

00:03:58.880 --> 00:04:00.200
Commit-Bit

00:04:00.200 --> 00:04:02.100
wieder

00:04:02.100 --> 00:04:04.860
hochfahren, quasi aus

00:04:04.860 --> 00:04:06.880
erneuern lassen. Ja, es gab ja immer, dass halt die neuen

00:04:06.880 --> 00:04:08.780
Versionen deutlich einfacher zu implementieren sind

00:04:08.780 --> 00:04:10.860
bei PyPy, wenn das drin ist,

00:04:10.940 --> 00:04:12.680
was da in C-Extensions irgendwie dazukommen

00:04:12.680 --> 00:04:14.820
sollte, wollte, wenn ich das

00:04:14.820 --> 00:04:15.600
richtig verstanden hatte damals.

00:04:16.620 --> 00:04:18.780
Ja, also jedenfalls, der macht da jetzt auch mit.

00:04:19.160 --> 00:04:21.220
Und das wird auf jeden Fall spannend.

00:04:22.100 --> 00:04:22.940
Ein schnelles Python.

00:04:24.480 --> 00:04:25.500
Ja, genau.

00:04:27.520 --> 00:04:30.520
Ja, ansonsten hätte ich jetzt noch das,

00:04:31.140 --> 00:04:32.980
ich habe ja jetzt mich auch hier an dieser Stelle

00:04:32.980 --> 00:04:34.360
schon irgendwie ein paar Mal beschwert

00:04:34.360 --> 00:04:37.660
über irgendwie sehr holprige Updates von Python.

00:04:38.080 --> 00:04:38.100
Über mich?

00:04:38.100 --> 00:04:38.160
Über dich.

00:04:38.160 --> 00:04:38.600
Entschuldigung.

00:04:38.880 --> 00:04:39.480
Ja, gut.

00:04:40.260 --> 00:04:41.280
Über Pydentic 2,

00:04:41.800 --> 00:04:43.400
über den Umstieg von Pydentic 1 auf 2.

00:04:43.640 --> 00:04:45.920
Und jetzt haben das andere Leute auch gemacht,

00:04:46.280 --> 00:04:48.880
Simon Willison hat da in letzter Zeit relativ viel zu gepostet,

00:04:48.960 --> 00:04:50.740
dass er das irgendwie ungünstig fand.

00:04:51.280 --> 00:04:52.720
Und da habe ich dann auch so Sachen gesehen wie,

00:04:53.100 --> 00:04:57.340
es gab da ein Issue zu, wo dann einer von Netflix oder so

00:04:57.340 --> 00:04:59.520
in relativ freundlichem Ton zunächst schrieb,

00:04:59.920 --> 00:05:04.560
das macht bei uns sehr viel Arbeit und das war jetzt alles nicht so günstig.

00:05:04.780 --> 00:05:06.500
Und ich habe dann geguckt, der hat dann auch irgendwann beschrieben,

00:05:06.600 --> 00:05:07.920
welche Issues, die da reingelaufen sind.

00:05:08.280 --> 00:05:09.980
Und das war halt zum Beispiel auch einer von den Dingern,

00:05:10.180 --> 00:05:12.640
in die ich da reingerannt bin.

00:05:14.040 --> 00:05:17.240
ja, genau, der meinte dann

00:05:17.240 --> 00:05:19.260
so, tja, also sauberer wäre es gewesen, wenn man

00:05:19.260 --> 00:05:21.040
das Paket irgendwie umbenannt hätte oder so

00:05:21.040 --> 00:05:23.200
und das wollten sie aber nicht machen

00:05:23.200 --> 00:05:25.080
und dann haben sie gesagt, nee, das geht auch

00:05:25.080 --> 00:05:27.020
so oder geht so, aber es ging alles nicht und es war

00:05:27.020 --> 00:05:28.020
relativ furchtbar, also

00:05:28.020 --> 00:05:31.100
gerade wenn man eine Library ist, hat man damit halt

00:05:31.100 --> 00:05:32.860
ein großes Problem, weil man nicht kontrollieren kann,

00:05:33.380 --> 00:05:35.120
was in der Applikation, die

00:05:35.120 --> 00:05:36.960
einen benutzt, halt irgendwie für eine

00:05:36.960 --> 00:05:38.980
Pidentic-Version ist und zum Beispiel

00:05:38.980 --> 00:05:40.980
FastAPI hat damit auch ein Riesenproblem gehabt

00:05:40.980 --> 00:05:43.120
und wie die das dann letztendlich gemacht

00:05:43.120 --> 00:05:44.900
haben, ist, sie haben halt so einen Flag eingeführt,

00:05:45.000 --> 00:05:47.120
Pydentic V2, und machen

00:05:47.120 --> 00:05:49.200
dann jetzt gerade sowas wie, if Pydentic

00:05:49.200 --> 00:05:51.100
V2, 500

00:05:51.100 --> 00:05:53.000
Zeilen eingerückt, irgendwie

00:05:53.000 --> 00:05:55.140
Kompatibilitätsleer, und dann

00:05:55.140 --> 00:05:57.000
else, und dann sonst, und das

00:05:57.000 --> 00:05:59.100
haben sie an mehreren Stellen, das ist wirklich absolut schrecklich.

00:05:59.820 --> 00:06:01.140
Naja, aber so sieht's halt

00:06:01.140 --> 00:06:03.060
aus, also das war, dieses Update war

00:06:03.060 --> 00:06:04.940
nicht wirklich

00:06:04.940 --> 00:06:06.980
reibungslos, sondern da haben

00:06:06.980 --> 00:06:08.160
viele Leute irgendwie eine Menge

00:06:08.160 --> 00:06:11.300
Schweiß gelassen, naja.

00:06:11.380 --> 00:06:11.840
Also nicht durch.

00:06:12.580 --> 00:06:14.840
Okay, also gut, wenn man es nicht zu sehr drin hat.

00:06:14.900 --> 00:06:15.760
Ich habe tatsächlich auch

00:06:15.760 --> 00:06:18.140
zwischendurch noch auf eins dependen müssen,

00:06:18.400 --> 00:06:19.820
weil da so bei zwei Sachen nicht so ging,

00:06:19.940 --> 00:06:21.740
was jetzt irgendwie geht, aber ja.

00:06:22.940 --> 00:06:23.800
Ein bisschen nervig.

00:06:24.680 --> 00:06:25.400
Johannes, hast du noch was?

00:06:26.720 --> 00:06:28.900
Nee, also in der TypeScript-Welt

00:06:28.900 --> 00:06:29.540
gibt es sowas nicht.

00:06:30.120 --> 00:06:32.500
Aber jetzt können wir uns über TypeScript-Versionen unterhalten.

00:06:34.180 --> 00:06:34.540
Apropos,

00:06:34.620 --> 00:06:35.920
ich habe gehört, dass ein neues Buch erschienen

00:06:35.920 --> 00:06:36.780
in der TypeScript-Welt.

00:06:37.340 --> 00:06:39.540
Echt, was? Das ist mir ganz neu.

00:06:39.640 --> 00:06:41.420
Ja, ich glaube, das muss der Stefan mal so ein bisschen erzählen.

00:06:41.500 --> 00:06:43.680
Ist das jetzt mein Intro, oder was?

00:06:43.880 --> 00:06:45.800
Ja, das war die softeste Überleitung.

00:06:46.160 --> 00:06:48.020
Ja, das war der softeste Übergang,

00:06:48.180 --> 00:06:48.780
den der Dominik macht.

00:06:48.900 --> 00:06:50.220
Ich habe das jetzt total spannend gefunden,

00:06:50.500 --> 00:06:53.620
weil es wird ja immer so

00:06:53.620 --> 00:06:55.440
gemunkert,

00:06:55.620 --> 00:06:57.480
dass im Web-Bereich

00:06:57.480 --> 00:06:59.320
gibt es ja quasi alle drei Minuten

00:06:59.320 --> 00:07:00.500
irgendeinen neuen Fachbegriff

00:07:00.500 --> 00:07:02.900
oder irgendeinen neuen Bibliothek-Namen

00:07:02.900 --> 00:07:04.880
oder irgendein neues JavaScript-Framework,

00:07:05.560 --> 00:07:07.740
das irgendeinen abstrusen

00:07:07.740 --> 00:07:09.480
Namen hat, mit dem

00:07:09.480 --> 00:07:11.240
sie alle nachher irgendwie auseinandersetzen müssen.

00:07:11.500 --> 00:07:15.900
und das ist jetzt das zweite Mal, dass ich so in diese Python-Ecke reinschaue

00:07:15.900 --> 00:07:18.300
und denke mir, hey, komm, das ist ja da genau das Gleiche.

00:07:19.200 --> 00:07:23.000
Den ersten Namen, den ich erkannt habe, das war FastAPI,

00:07:23.700 --> 00:07:29.080
weil tatsächlich, das ist spannend, ich bin jetzt seit vier, fünf Monaten

00:07:29.080 --> 00:07:32.400
bei uns in der Firma mit einer Gruppe Python-Developern unterwegs,

00:07:32.760 --> 00:07:35.620
Data Scientist, ganz klassisch, du hast einen Data Scientist

00:07:35.620 --> 00:07:39.920
und das Tool der Wahl ist Python, die Bibliotheken sind da,

00:07:40.600 --> 00:07:45.340
Das Übliche mit Langchain, Pipa Pro für diese ganze LLM-Sache.

00:07:45.600 --> 00:07:49.800
Und das war so mein erstes Intro in dieser Python-Welt.

00:07:49.900 --> 00:07:55.000
Und ich bin schon massiv gescheitert daran, dass ich den Package-Manager auswähle, der passt.

00:07:55.000 --> 00:08:00.500
Da gibt es ja dann Conda, Anaconda, Pep oder sind das ganz andere?

00:08:00.620 --> 00:08:02.980
Keine Ahnung. Also wie gesagt, das ist ja schon wieder vorbei.

00:08:03.920 --> 00:08:05.740
Aber ich weiß, dass ich FastAPI

00:08:05.740 --> 00:08:07.400
nach langen, langen Gesprächen mit unseren

00:08:07.400 --> 00:08:09.800
Python-Devs in unser Architektur-

00:08:09.800 --> 00:08:11.320
Diagramm eingetragen habe für

00:08:11.320 --> 00:08:13.340
irgendeinen Server, den wir gemacht haben.

00:08:13.720 --> 00:08:15.220
Das war eben das Erste, wo ich mir gedacht habe,

00:08:15.400 --> 00:08:17.620
da kenne ich mich jetzt aus, bei FastAPI

00:08:17.620 --> 00:08:18.420
da kann ich mitreden.

00:08:20.460 --> 00:08:20.900
Funktioniert

00:08:20.900 --> 00:08:23.580
Multithreaded, aber nicht Async.

00:08:23.920 --> 00:08:24.480
Ist das richtig?

00:08:26.020 --> 00:08:27.700
Also kann man wahrscheinlich so betreiben,

00:08:27.860 --> 00:08:29.480
wenn man wirklich will, aber nee, es ist tatsächlich

00:08:29.480 --> 00:08:31.600
Async. Also unter FastAPI

00:08:31.600 --> 00:08:33.020
liegt normalerweise

00:08:33.020 --> 00:08:34.960
so würde ich jetzt mal sagen, wenn man

00:08:34.960 --> 00:08:36.860
das so betreibt, wie es gedacht ist,

00:08:37.060 --> 00:08:38.900
halt Stalett

00:08:38.900 --> 00:08:40.440
beziehungsweise UV-Corn

00:08:40.440 --> 00:08:42.280
und das ist halt sozusagen die

00:08:42.280 --> 00:08:45.140
Lib-UV, also das ist halt eine Adaption

00:08:45.140 --> 00:08:46.940
von Nen-UV, was halt auch unter der

00:08:46.940 --> 00:08:48.740
Event-Loop bei Node.js

00:08:48.740 --> 00:08:50.500
liegt halt für Python.

00:08:51.580 --> 00:08:52.900
Ja, und also ist

00:08:52.900 --> 00:08:54.780
halt quasi genauso schnell dann auch

00:08:54.780 --> 00:08:56.180
und ist Async, ja.

00:08:57.120 --> 00:08:58.220
Cool. Das war die

00:08:58.220 --> 00:09:00.020
zweite, war dann, dass ich

00:09:00.020 --> 00:09:02.540
versucht habe, über

00:09:02.540 --> 00:09:05.000
PyO3 eine Brücke

00:09:05.000 --> 00:09:06.880
zwischen Async Rust und

00:09:06.880 --> 00:09:08.880
Async Python einmal zu schreiben. Das war spannend.

00:09:09.140 --> 00:09:09.860
Das war richtig cool.

00:09:10.620 --> 00:09:12.280
Was mich da beeindruckt hat,

00:09:12.800 --> 00:09:14.980
und mit dem habe ich nicht gerechnet, ist, dass

00:09:14.980 --> 00:09:17.200
das vollen Frankischen Interface von Python

00:09:17.200 --> 00:09:19.020
ja fantastisch ist.

00:09:19.280 --> 00:09:21.040
Also du hast dort dein kompiliertes

00:09:21.040 --> 00:09:22.580
SO-Modul dazu und du kannst

00:09:22.580 --> 00:09:25.140
auf die Objektliste zugreifen

00:09:25.140 --> 00:09:26.600
und kannst die Identifier herauslesen.

00:09:27.280 --> 00:09:28.900
Also das Kompilieren

00:09:28.900 --> 00:09:30.960
vom Rust-Code war auf jeden Fall anspruchsvoller,

00:09:31.420 --> 00:09:33.560
als wir nachher die Symbole in Python

00:09:33.560 --> 00:09:35.440
zu loben und zu verwenden, das war richtig,

00:09:35.440 --> 00:09:36.500
richtig beeindruckend. Also

00:09:36.500 --> 00:09:39.460
coole Sache, möchte ich mir auf jeden Fall mehr anschauen.

00:09:39.740 --> 00:09:41.480
Aber das ist es. Also das sind

00:09:41.480 --> 00:09:42.480
meine Python-Kenntnisse.

00:09:43.420 --> 00:09:45.480
Ja, aber ich finde auch, das Benutzen von

00:09:45.480 --> 00:09:47.100
Python ist halt das, was so Spaß macht.

00:09:48.520 --> 00:09:49.680
Also High-Level-Interface,

00:09:49.760 --> 00:09:50.940
ich glaube, ist sehr gut geeignet.

00:09:51.300 --> 00:09:53.360
Py3, auch ein cooles Beispiel. Da gibt es die meisten

00:09:53.360 --> 00:09:55.180
Sachen, die es irgendwie kann. Ich glaube, was es nicht kann, ist

00:09:55.180 --> 00:09:57.280
irgendwie Iteratoren

00:09:57.280 --> 00:09:58.980
ausspucken, richtig, oder so, oder Generatoren.

00:09:59.320 --> 00:10:00.800
Ja, das wird wahrscheinlich schwierig sein.

00:10:01.420 --> 00:10:02.500
Das kann ich mir gut vorstellen.

00:10:03.180 --> 00:10:03.540
Keine Ahnung.

00:10:03.700 --> 00:10:06.100
Da ist dieses Typsystem von Rust halt doch sehr, sehr eigen

00:10:06.100 --> 00:10:11.920
und sehr schwierig, in andere Sprachen zu integrieren, nehme ich mal an.

00:10:12.360 --> 00:10:15.220
Ja, aber ich hatte ja als News ja auch quasi noch ein bisschen Werbung gemacht für dein Buch.

00:10:15.320 --> 00:10:16.960
Vielleicht willst du dazu noch irgendwie kurz was sagen?

00:10:18.020 --> 00:10:20.000
Ja, dankeschön. Danke für diese Überleitung.

00:10:20.660 --> 00:10:26.100
Ich habe tatsächlich in den letzten Jahren TypeScript-Bücher geschrieben.

00:10:26.740 --> 00:10:31.940
Das erste Buch, das ich geschrieben habe, war in 2020 TypeScript in 50 Lessons,

00:10:32.020 --> 00:10:34.680
das beim Smashing Magazine Verlag rausgekommen ist,

00:10:34.760 --> 00:10:43.860
das als angenehmer, unaufgeregter Einstieg in TypeScript als Typsystem auf JavaScript gedacht ist.

00:10:43.860 --> 00:10:49.300
Das Zielpublikum waren Entwicklerinnen und Entwickler, die JavaScript schon kennen,

00:10:49.600 --> 00:10:54.220
sich dort auch schon wohlfühlen und jetzt merken, jetzt müssen sie TypeScript verwenden,

00:10:55.020 --> 00:11:12.160
Wir brauchen die Info, warum man das erstens überhaupt haben will und zweitens, wie das jetzt so richtig funktioniert und warum es da so viel Syntax gibt und warum das so kompliziert ausschaut und versucht, das grundlegende System, Typsystem runterzubrechen auf einfach zu verdauende Lektionen.

00:11:13.720 --> 00:11:30.480
Genau, das war das Ziel von dem Buch, das habe ich dann zufälligerweise in 50 Lektionen geschafft, das war ein Riesenspaß, das war quasi mein Corona-Projekt, mein erstes Lockdown-Projekt, wobei es stimmt nicht, ich habe zwischen dem ersten und dem zweiten Lockdown tatsächlich das meiste geschrieben.

00:11:30.480 --> 00:11:34.860
Das ist auch tatsächlich ein Schicksal, das sieht auch super aus, also von außen, wenn du in den Schrank stellst.

00:11:35.220 --> 00:11:40.980
Wir wissen das, weil wir dieses Buch auch alle haben, zwar als Paltenentwickler, was natürlich auch schon was heißt.

00:11:41.720 --> 00:11:44.920
Das macht mich irrsinnig happy.

00:11:45.060 --> 00:11:46.000
Ihr kennt sich das nicht vorstellen.

00:11:46.160 --> 00:11:48.800
Das sind diese unglaublich schönen Momente,

00:11:48.900 --> 00:11:49.300
wenn man sieht,

00:11:50.140 --> 00:11:52.340
dass das Buch tatsächlich an Leute kommt

00:11:52.340 --> 00:11:53.560
und Leute das verwenden.

00:11:53.700 --> 00:11:55.780
Also die Lesepäntchen gesehen herrlich spitze.

00:11:56.180 --> 00:11:58.540
Und die Optik ist wirklich ganz, ganz besonders,

00:11:58.720 --> 00:12:01.580
weil das war eigentlich auch ein Grund,

00:12:01.660 --> 00:12:03.480
warum ich mit Smashing Magazine zusammenarbeiten wollte.

00:12:03.660 --> 00:12:06.720
Die haben einfach irrsinnig viel Liebe zum Detail

00:12:06.720 --> 00:12:10.240
und versuchen wirklich sehr individuelle Bücher zu machen,

00:12:10.380 --> 00:12:11.700
haben eine wunderschöne Typografie,

00:12:11.780 --> 00:12:12.660
die sauber zu lesen ist

00:12:12.660 --> 00:12:16.220
und verzetteln sich dann in kleinen Finessen so stark.

00:12:16.600 --> 00:12:17.680
Und ich habe zum Beispiel,

00:12:17.760 --> 00:12:20.220
das Cover wurde gestaltet von Rob Draper,

00:12:20.520 --> 00:12:22.280
den habe ich tatsächlich in Düsseldorf kennengelernt,

00:12:22.440 --> 00:12:23.420
auf der Björn Tellerrand,

00:12:24.060 --> 00:12:28.100
der als Künstler die Intro-Grafiken

00:12:28.100 --> 00:12:29.800
zu den Golden Globes gemacht hat,

00:12:29.900 --> 00:12:32.440
für Nike und BMX-Fahrräder

00:12:32.440 --> 00:12:33.820
beziehungsweise Schuhe designt hat.

00:12:34.640 --> 00:12:35.460
Und der mich gefragt hat,

00:12:35.460 --> 00:12:36.780
ich habe ihm eine E-Mail geschrieben,

00:12:36.880 --> 00:12:37.960
hey, der Robert ist cool,

00:12:38.080 --> 00:12:39.480
möchtest du mein Buch designen?

00:12:39.560 --> 00:12:41.120
Ja, passt. Und ich habe gedacht, hey, wow, cool.

00:12:41.260 --> 00:12:43.200
Ich hoffe, er kostet jetzt nicht eine Million oder so.

00:12:43.700 --> 00:12:47.840
Und er hat tatsächlich dann unser Buch, also das Buch gestaltet,

00:12:49.100 --> 00:12:56.040
also versucht er mit diesem Kapitel in Lays ein bisschen das Ganze zugänglich zu machen,

00:12:56.180 --> 00:12:58.500
freundlich zu machen. Das war uns ganz, ganz wichtig.

00:12:59.300 --> 00:13:03.140
Und die Person, die nachher, also die Ari, die nachher das Ganze gesetzt hat

00:13:03.140 --> 00:13:07.080
und versucht hat, ein Produkt daraus zu machen, hat dann auch recherchiert

00:13:07.080 --> 00:13:09.260
und hat zum Beispiel das Lesebändchen, das rote Lesebändchen,

00:13:09.740 --> 00:13:14.440
in der Farbe bestellt von den roten Unterlinien in Visual Studio Code.

00:13:14.640 --> 00:13:16.940
Das heißt, das ist der gleiche Farbton.

00:13:17.460 --> 00:13:19.260
Und so tief ins Detail geht es dort.

00:13:19.380 --> 00:13:23.080
Und das ist halt einfach absolut herrlich für mich,

00:13:23.140 --> 00:13:25.000
der praktisch nur den Text beigetragen hat,

00:13:25.080 --> 00:13:29.980
dass du siehst, wie andere Leute sich so investieren in dieses Projekt

00:13:29.980 --> 00:13:33.180
und versuchen, gemeinsam da irgendwas Cooles draus zu machen.

00:13:33.680 --> 00:13:35.000
Also da kriege ich heute noch Gänsehaut.

00:13:35.040 --> 00:13:39.240
Und es ist ja für mich so, ich weiß, es ist mein Buch, aber es ist nicht nur mein Buch.

00:13:39.440 --> 00:13:41.620
Also da sind so viele Leute daran beteiligt gewesen.

00:13:41.840 --> 00:13:44.880
Es war ein irrsinnig cooler Effort von so vielen Menschen.

00:13:45.300 --> 00:13:46.760
Und das macht mich einfach jedes Mal wieder glücklich,

00:13:46.760 --> 00:13:51.480
wenn ich dann sehe, dass das Leute auch so sehen, sie das in die Bücherregale stellen.

00:13:51.720 --> 00:13:55.080
Oder das Beste, was du machen kannst, hast du einen Zoom-Call,

00:13:55.460 --> 00:13:57.480
stell es in den Hintergrund und schick mir ein Foto von dem Zoom-Call.

00:13:57.580 --> 00:13:59.940
Das ist das Allerbeste. Das macht mir die größte, größte Freude.

00:14:00.980 --> 00:14:06.140
Es hat eine Freude für mich gemacht, wie er ein Interview für sein Start-up gemacht hat.

00:14:06.260 --> 00:14:07.880
Auf einmal sehe ich, da ist mein Buch im Hintergrund.

00:14:08.440 --> 00:14:10.520
Herrlich, also macht riesen Spaß.

00:14:11.820 --> 00:14:13.320
Das war das erste TypeScript-Buch.

00:14:13.400 --> 00:14:15.000
Ich habe dann noch ein zweites TypeScript-Buch geschrieben.

00:14:15.180 --> 00:14:17.880
Das ist erst im September rausgekommen, also ist noch ganz, ganz frisch.

00:14:18.860 --> 00:14:22.780
Das ist das TypeScript-Cookbook, das jetzt mit O'Reilly veröffentlicht worden ist.

00:14:24.200 --> 00:14:26.600
Das war praktisch eine Auftragsarbeit.

00:14:26.600 --> 00:14:31.040
Also O'Reilly hat so diese Acquisition Editors, die suchen halt noch potenziellen Autoren,

00:14:31.460 --> 00:14:34.640
schlagen denen Buchprojekte vor oder schlagen vor, hey, möchtest du zu dem Thema was schreiben?

00:14:35.800 --> 00:14:40.840
Und sie haben gesagt, sie wollen ein TypeScript-Buch veröffentlichen in diesem Stil wie TypeScript in 50 Lessons,

00:14:40.940 --> 00:14:43.560
ob ich mir vorstellen kann, noch ein solches zu schreiben.

00:14:44.340 --> 00:14:46.740
Und am Anfang haben wir gedacht, nein, das geht nicht, ich habe jetzt schon ein Buch geschrieben,

00:14:46.960 --> 00:14:54.000
ich habe halt einfach eine gewisse Ansicht, eine gewisse Stimme, eine gewisse Idee zu dem Ganzen.

00:14:54.000 --> 00:15:08.620
Habe aber gedacht, naja, meine Saisonreile probierst du doch mal, dass du kurz ein Inhaltsverzeichnis unterschreibst, wie du dir ein zweites Buch vorstellen kannst. Und gerade habe ich 100 weitere Einträge gehabt innerhalb von drei Stunden. Also ich bin mir am Nachmittag hingesetzt und habe gedacht, ups, wow, da ist ein Buch da.

00:15:09.720 --> 00:15:16.480
Ich bin mit denen in einen Vertrag gegangen und habe dann versucht, den Nachfolger vom TypeScript in 50 Lessons Buch zu schreiben.

00:15:17.000 --> 00:15:23.540
Wenn du in TypeScript in 50 Lessons lernst, wie das Typsystem funktioniert, lernst du im TypeScript QuickBook alle Dinge, die schief gehen können.

00:15:24.520 --> 00:15:28.360
Dinge, die, wenn du wirklich Programme damit schreibst, wo du merkst, da passt gerade was nicht,

00:15:28.880 --> 00:15:31.440
da spielt das Typsystem nicht so mit, wie ich mir das denke,

00:15:31.900 --> 00:15:36.780
beziehungsweise brauche ich halt irgendeine Technik oder irgendein Prinzip oder irgendein Pattern,

00:15:36.780 --> 00:15:39.340
das ich anwenden kann, um einem gewissen Problem.

00:15:39.480 --> 00:15:43.040
Im Moment, ich dachte jetzt, so Typen hast du damit nichts mehr schief gehen kann.

00:15:43.440 --> 00:15:47.480
Und mit Typen, mit sicheren statischen Typen sind die Sprachen immer ganz besonders gut.

00:15:48.200 --> 00:15:53.920
Genau, da beschreibt man nur mehr Programme, die nur mehr funktionieren und man hat keine Bugs mehr und es ist super-happy.

00:15:54.220 --> 00:15:54.820
Ja, genau.

00:15:55.900 --> 00:16:00.320
Ja, also ich bin eine super Überleitung tatsächlich auf das Thema, was wir heute machen wollen, oder?

00:16:01.040 --> 00:16:01.340
Ja.

00:16:02.660 --> 00:16:06.680
Also ganz herzlichen Dank, dass du heute da bist, Stefan, das freut uns sehr.

00:16:07.440 --> 00:16:09.520
In Python haben wir ja von Typen auch schon

00:16:09.520 --> 00:16:11.180
das eine, andere Mal am Rande gehört.

00:16:11.400 --> 00:16:13.520
Ja, wir haben diese Episode immer lange vor uns hergeschoben,

00:16:13.640 --> 00:16:15.520
weil wir uns nie ausreichend vorbereitet

00:16:15.520 --> 00:16:17.320
gefühlt haben dafür, weil das halt so ein großes Thema ist.

00:16:17.380 --> 00:16:19.640
Es gibt auch eine ganz große Anti-Fan-Gemeinde

00:16:19.640 --> 00:16:21.060
in Python für Types irgendwie.

00:16:21.800 --> 00:16:23.480
Es gibt auch viele, die das nicht so mögen, ja.

00:16:24.740 --> 00:16:25.520
Wie seid ihr

00:16:25.520 --> 00:16:27.220
da so drauf? Also

00:16:27.220 --> 00:16:29.480
habt ihr jetzt Typen schon in eurem Python-Code drinnen

00:16:29.480 --> 00:16:31.280
oder ist das eher noch so das Buch mit

00:16:31.280 --> 00:16:33.360
sieben Siegeln, das ihr nicht öffnen wollt?

00:16:33.840 --> 00:16:35.660
Annotationen nutze ich persönlich sehr gerne

00:16:35.660 --> 00:16:37.560
insbesondere dann, wenn ich mit anderen Menschen

00:16:37.560 --> 00:16:39.700
arbeite, um einfach so zu dokumentieren,

00:16:39.820 --> 00:16:40.640
was macht das denn überhaupt.

00:16:41.740 --> 00:16:43.780
Das heißt aber nicht, dass das immer stimmt, was da steht.

00:16:47.320 --> 00:16:48.420
Das ist aber gefährlich damit.

00:16:48.800 --> 00:16:53.540
Ja, also ich

00:16:53.540 --> 00:16:55.240
verwende sie auch schon und ich habe halt

00:16:55.240 --> 00:16:57.080
ein Projekt mal so komplett

00:16:57.080 --> 00:16:59.200
irgendwie annotiert, einfach nur auch,

00:16:59.340 --> 00:17:01.300
weil ich wissen wollte, wie schwierig ist es

00:17:01.300 --> 00:17:03.020
denn nun, wie weh tut es denn

00:17:03.020 --> 00:17:03.880
irgendwie.

00:17:05.660 --> 00:17:07.740
Und ja, das ging schon,

00:17:07.880 --> 00:17:09.720
aber es war auch, also ich habe

00:17:09.720 --> 00:17:11.560
da jetzt nicht so wahnsinnig viel

00:17:11.560 --> 00:17:12.640
irgendwie

00:17:12.640 --> 00:17:15.340
Nutzen rausziehen können, aber

00:17:15.340 --> 00:17:17.600
ich hatte auch vorher neben dem Ding halt auch schon

00:17:17.600 --> 00:17:19.180
100% Test-Coverage, insofern

00:17:19.180 --> 00:17:21.660
war da einfach wahrscheinlich nicht mehr so viel

00:17:21.660 --> 00:17:23.800
zu, ja auch

00:17:23.800 --> 00:17:25.560
das habe ich ja gemacht, um es mal

00:17:25.560 --> 00:17:26.100
gemacht zu haben.

00:17:26.920 --> 00:17:29.420
Ich habe tatsächlich in den Projekten bei mir jetzt Enforced

00:17:29.420 --> 00:17:31.540
MyPi Precommit Hook.

00:17:31.940 --> 00:17:33.600
Das ist auch schon, damit gehe ich ziemlich vielen

00:17:33.600 --> 00:17:35.500
Leuten auf die Nerven, aber

00:17:35.500 --> 00:17:37.300
Gut, dann kannst du überall Objekt hinschreiben, oder?

00:17:37.420 --> 00:17:39.340
Das zählt doch auch. Ja, okay, also

00:17:39.340 --> 00:17:41.540
da sind die meisten noch nicht draufgekommen.

00:17:42.800 --> 00:17:43.740
Oh, da habe ich jetzt ein Geheimnis

00:17:43.740 --> 00:17:44.300
verraten, hups.

00:17:46.100 --> 00:17:47.240
Annie, oder? Annie, Annie.

00:17:47.540 --> 00:17:48.300
So, zack.

00:17:49.460 --> 00:17:51.520
Also ich bin beeindruckt von der 100%

00:17:51.520 --> 00:17:53.700
Test-Courage. Also ich bin

00:17:53.700 --> 00:17:55.780
leider Gottes der faulste

00:17:55.780 --> 00:17:56.200
Tester.

00:17:57.420 --> 00:17:58.540
Diesseits der Donau.

00:18:00.540 --> 00:18:01.300
Ich sage immer,

00:18:01.300 --> 00:18:03.340
also ich habe diesen Spruch

00:18:03.340 --> 00:18:05.040
gehabt, wie ich noch in einer Agentur gearbeitet habe,

00:18:05.100 --> 00:18:06.480
dass ich sage, ja, getestet wird beim Kunden,

00:18:06.600 --> 00:18:08.700
nicht, wenn es in Production ist, es soll reichen.

00:18:09.780 --> 00:18:14.140
Aber ich, keine Ahnung, liegt es an der Software,

00:18:14.280 --> 00:18:15.700
die ich schreibe oder an der Rolle, in der ich bin?

00:18:16.380 --> 00:18:18.780
Ich bin sehr, sehr selten jemand,

00:18:19.020 --> 00:18:21.320
der wirklich ausgiebige Testsuit schreibt.

00:18:22.140 --> 00:18:24.140
Also das ist, glaube ich,

00:18:24.140 --> 00:18:26.200
als ich auch Schärfe habe, das ist, glaube ich,

00:18:26.200 --> 00:18:27.060
meine größte Schwäche.

00:18:27.880 --> 00:18:30.780
Ja, 100% Courage ist auch schon sehr...

00:18:30.780 --> 00:18:33.280
Ja, ich finde es beeindruckend, wirklich.

00:18:33.360 --> 00:18:34.820
Ja, das haben wir in dem Projekt, in dem ich bin,

00:18:34.920 --> 00:18:36.940
Ach, 100%, also 100% Branch

00:18:36.940 --> 00:18:38.720
Coverage sogar. Und

00:18:38.720 --> 00:18:40.980
TypeScript. Also es ist ja oft

00:18:40.980 --> 00:18:42.380
so, dass man das so ein bisschen als

00:18:42.380 --> 00:18:44.840
gegensätzliche Pole ansieht,

00:18:44.960 --> 00:18:46.820
sag ich mal. Die einen machen Typen und die anderen machen

00:18:46.820 --> 00:18:48.900
Testing. Und das ist schön, Stefan,

00:18:48.940 --> 00:18:50.500
dass du das jetzt bestätigt hast, aber

00:18:50.500 --> 00:18:52.960
Ich bin quasi

00:18:52.960 --> 00:18:55.420
das Typen-Paradebeispiel.

00:18:56.000 --> 00:18:56.820
Ich meine, das Ding ist,

00:18:57.140 --> 00:18:58.760
JavaScript und Python

00:18:58.760 --> 00:19:00.680
haben ja die gleiche Eigenschaft,

00:19:00.820 --> 00:19:03.200
dass beides in der Praxis

00:19:03.200 --> 00:19:04.460
dynamisch typisiert

00:19:04.460 --> 00:19:06.520
Sprachen sind. Sprich, natürlich gibt es

00:19:06.520 --> 00:19:08.260
Typen, sonst könntest du mit den ganzen Werten nichts

00:19:08.260 --> 00:19:10.620
anfangen. Es ist aber relativ egal, was das für ein

00:19:10.620 --> 00:19:11.760
ist. Du kannst dann

00:19:11.760 --> 00:19:14.140
ein Number oder ein Integer einer

00:19:14.140 --> 00:19:16.460
Variable zuweisen und im nächsten Schritt

00:19:16.460 --> 00:19:18.400
dann String und keiner regt sich auf und keiner beschwert sich.

00:19:18.440 --> 00:19:19.400
Das funktioniert halt einfach.

00:19:20.300 --> 00:19:22.200
Oder du kannst verschiedene Typen mischen. Du kannst

00:19:22.200 --> 00:19:23.600
ein String mit einer Zahl kombinieren.

00:19:23.720 --> 00:19:24.280
Das geht nicht.

00:19:25.440 --> 00:19:27.520
Okay, cool. Dann seid ihr schon mal einen Riesenschritt weiter

00:19:27.520 --> 00:19:29.020
als in JavaScript.

00:19:29.120 --> 00:19:31.260
Das ist ja das große Problem an JavaScript, oder?

00:19:31.340 --> 00:19:33.360
Dass du solche implizite Konversionen

00:19:33.360 --> 00:19:34.820
drin hast. Ja, also

00:19:34.820 --> 00:19:37.620
das heißt ja immer weak getyped

00:19:37.620 --> 00:19:39.100
versus strong getyped, aber

00:19:39.100 --> 00:19:40.620
ich weiß nicht, ob das irgendein Sinn ergibt.

00:19:41.220 --> 00:19:43.640
Aber diese ganzen Bezeichnungen sind ja alle nur so ein bisschen.

00:19:44.580 --> 00:19:45.360
Also die schöneren

00:19:45.360 --> 00:19:47.300
Bezeichnungen sind meiner Meinung nach statisch und

00:19:47.300 --> 00:19:48.580
dynamisch, wo du einfach weißt, okay,

00:19:49.500 --> 00:19:51.740
definierst du den Typen im Vorhinein

00:19:51.740 --> 00:19:53.500
oder wird er definiert durch die Verwendung?

00:19:54.600 --> 00:19:55.360
Weak und strong,

00:19:55.560 --> 00:19:56.560
also schwach und stark,

00:19:56.560 --> 00:19:58.560
sind sehr

00:19:58.560 --> 00:20:00.720
schwache Bezeichnungen, meiner Meinung

00:20:00.720 --> 00:20:02.360
nach. C zum Beispiel hat

00:20:02.360 --> 00:20:03.980
ein statisches

00:20:03.980 --> 00:20:06.140
Typsystem, aber ein sehr, sehr schwaches. Ob du jetzt

00:20:06.140 --> 00:20:08.220
einen Character hast oder ein Integer oder irgendwas anderes,

00:20:08.360 --> 00:20:09.740
es ist einfach komplett wurscht.

00:20:10.400 --> 00:20:12.440
Du kannst alles damit machen. Und kannst auch hin und her wechseln

00:20:12.440 --> 00:20:14.340
und kannst auch Bitfiddling mit allem möglichen

00:20:14.340 --> 00:20:16.340
Scheiß machen. Genau, genau, genau.

00:20:16.460 --> 00:20:18.380
Wundervolle Bühne. Und vor dem

00:20:18.380 --> 00:20:20.120
ist das Statische eigentlich das Wichtige,

00:20:20.220 --> 00:20:22.820
weil es eine ein bisschen andere Herangehensweise

00:20:22.820 --> 00:20:23.980
ans Programmieren

00:20:23.980 --> 00:20:25.820
voraussetzt.

00:20:26.180 --> 00:20:28.400
Du machst dir einfach mehr Gedanken über

00:20:28.400 --> 00:20:30.240
die

00:20:30.240 --> 00:20:31.660
mögliche Wertemenge

00:20:31.660 --> 00:20:33.920
einer Variable, bevor du

00:20:33.920 --> 00:20:36.040
an wer zuweist. Das schließt jetzt nicht aus,

00:20:36.100 --> 00:20:38.140
dass du sagen kannst, hey, du bekommst

00:20:38.140 --> 00:20:39.980
einen Typen durch Typ-Inferenz, das mache

00:20:39.980 --> 00:20:42.020
ich sehr, sehr gerne, weil ich sage, hey, diese Variable

00:20:42.020 --> 00:20:44.000
x ist 3 und dann weißt du,

00:20:44.080 --> 00:20:45.840
dass das ein Number oder Integer oder was auch immer ist.

00:20:45.940 --> 00:20:47.820
Das geht natürlich auch, das machen auch moderne

00:20:47.820 --> 00:20:49.220
Programmiersprachen sehr, sehr, sehr gerne.

00:20:51.180 --> 00:20:51.920
Grundlegend, dass du halt

00:20:51.920 --> 00:20:53.420
mit wenig Annotationen machen kannst.

00:20:54.840 --> 00:20:55.240
Nichtsdestotrotz

00:20:55.240 --> 00:20:57.780
definierst du Verträge zwischen

00:20:57.780 --> 00:20:59.900
Bausteinen deines Codes, zwischen den Functions,

00:21:00.140 --> 00:21:02.280
zwischen Methoden in deinen Klassen etc.,

00:21:02.280 --> 00:21:05.560
in denen du sagst, du erwartest aber jetzt diesen Wertebereich und nichts anderes

00:21:05.560 --> 00:21:07.220
und du lässt auch nichts anderes zu.

00:21:08.000 --> 00:21:10.960
Und TypeScript ist meiner Meinung nach da sehr, sehr spannend,

00:21:11.580 --> 00:21:18.400
weil TypeScript versucht, eine sehr dynamische, dynamisch typisierte Programmiersprache

00:21:18.400 --> 00:21:20.700
und generell sehr dynamische Programmiersprache wie JavaScript

00:21:20.700 --> 00:21:23.160
in einer gewissen Art und Weise zu formalisieren.

00:21:23.160 --> 00:21:28.200
Also das Ziel ist ja jetzt nicht, dort eine komplett neue Programmiersprache zu definieren

00:21:28.200 --> 00:21:35.380
oder zu entwickeln, sondern auf Basis einer bestehenden irgendwie ein Regelwerk zu finden,

00:21:35.980 --> 00:21:39.980
damit alle beteiligten Programmierinnen und Programmierer irgendwas zu diskutieren haben

00:21:39.980 --> 00:21:41.480
und wissen, was da eigentlich vor sich geht.

00:21:41.660 --> 00:21:46.400
Nichts ist schlimmer, wenn du ein halbes Jahr, nachdem du dein Programm geschrieben hast,

00:21:46.440 --> 00:21:50.020
wieder zurückgehst und dir fragst, was war denn diese Variable X nochmal?

00:21:50.220 --> 00:21:51.640
Also was habe ich mir da eigentlich gedacht?

00:21:51.940 --> 00:21:54.480
Und dann hast du irgend so eine fette Wurst am Code und musst herauslesen,

00:21:54.520 --> 00:21:55.540
was du eigentlich damit machst.

00:21:56.280 --> 00:22:00.420
Und das ist etwas, was mich immer komplett verwirrt hat.

00:22:01.420 --> 00:22:05.860
Ich habe da nie ein funktionales Programmierparadigmen ausprobiert,

00:22:05.960 --> 00:22:07.980
viel mit asynchronen Promises gearbeitet in Not.

00:22:08.620 --> 00:22:11.740
Irgendwelche dynamischen Objekte gehabt, wo ich ständig neue Keys hinzugefügt habe

00:22:11.740 --> 00:22:12.560
und wieder entfernt habe.

00:22:12.640 --> 00:22:15.640
Und das war kurz und effektiv und schnell und schön.

00:22:16.340 --> 00:22:18.460
Und drei Monate später habe ich nicht mehr gewusst, was ich dort mache.

00:22:18.560 --> 00:22:20.760
Wenn ich das Programm heute lese, ich kenne mich nicht aus.

00:22:20.820 --> 00:22:22.440
Und ich würde es auch heute nicht mehr so machen.

00:22:22.720 --> 00:22:32.040
Einfach weil, gut österreichisch, sorry, Graut und Ruben einfach zusammenschmeißt und hofft, dass am Ende alles funktioniert.

00:22:32.580 --> 00:22:36.400
Und das ist gut für kleine Skripte, das ist gut, wenn du irgendwie geschwind was runterheckst.

00:22:36.460 --> 00:22:44.460
Aber wenn ihr wirklich mit einem Team versucht, reale Software zu machen, dann ist das, glaube ich, die niedrigste Schwelle, die du hast,

00:22:44.740 --> 00:22:51.220
um zu dokumentieren, was jetzt von deiner Software und von den Nutzern deiner Software überhaupt erwartet wird.

00:22:51.220 --> 00:23:12.800
Und ich glaube, deswegen sind Typen so wichtig. Und deswegen, glaube ich, sind Typen auch in Python sehr, sehr interessant, weil du ja da die gleichen Voraussetzungen hast. Also du musst ja wissen, was erwartet jetzt deine Funktion dort. Und je mehr Bibliotheken, die du hast, wie gesagt, ich wäre schon gesagt, ich bin jetzt in diesem Luncheon und LLM-Wahnsinn irgendwie gefangen, da hast du sehr, sehr komplexe Objekte, die du da hin und her schickst.

00:23:13.180 --> 00:23:19.500
Woher sollst du wissen, oder woher soll ich wissen, der kein Python schreibt, sondern nur lest, was da jetzt eigentlich erwartet wird und was ich da rauskriege?

00:23:19.520 --> 00:23:22.100
Das finde ich auch, also das tatsächlich so als Dokumentationstyp

00:23:22.100 --> 00:23:24.040
für Python ist das, was ich auch am häufigsten

00:23:24.040 --> 00:23:25.920
gerne mag, also in kleinen Closures,

00:23:26.040 --> 00:23:27.820
in kleinen Methoden oder Funktionen irgendwie

00:23:27.820 --> 00:23:30.040
die Argumente so zu annotieren,

00:23:30.240 --> 00:23:32.040
dass beim Riesen klar wird, was denn

00:23:32.040 --> 00:23:33.420
der Mensch da haben möchte, der

00:23:33.420 --> 00:23:34.820
diese API bereitstellt,

00:23:35.780 --> 00:23:37.700
dass ich das irgendwie zusammengebaut kriege oder so, oder

00:23:37.700 --> 00:23:39.260
verstehe, was er denn da braucht oder sowas.

00:23:39.960 --> 00:23:40.660
Das sehe ich anders.

00:23:40.660 --> 00:23:41.940
Ja, ich weiß nicht so.

00:23:45.300 --> 00:23:46.840
Aber das hätte ich ja heute hier.

00:23:47.180 --> 00:23:47.720
Ja, genau.

00:23:49.520 --> 00:24:04.260
Also ich finde, dass das Argument, was der Dominik bringt, das stimmt, wenn man nur simple Funktionen hat. Also wenn man wissen will, ob da jetzt ein Integer oder ein String rein muss. Und man hat vier Parameter und die haben alle simple Typen.

00:24:04.560 --> 00:24:24.420
Aber für mich fällt es auseinander, wenn die Typen komplex werden, weil dann hast du irgendwelche benannten Typen, die irgendwelche interne Struktur haben, die völlig opak ist und dann hast du 17 verschiedene Varianten davon und am Ende weißt du genauso wenig, was da rein muss und was nicht. Und das hat alles so seine Grenzen.

00:24:25.220 --> 00:24:43.300
Ja, ich habe letzte Woche mit einem Freund telefoniert, da haben wir uns auch kurz über Type Annotations unterhalten und der meinte so, ja, schön und gut und ich sehe die Vorteile und so, ich finde es einfach irgendwie hässlich, weil irgendwie, okay, die IDE, ja, okay, das ist eigentlich alles gesagt.

00:24:43.300 --> 00:24:45.080
die Ästhetik ist immer das Argument.

00:24:45.400 --> 00:24:45.580
Ja.

00:24:47.260 --> 00:24:49.200
IDE kann damit was anfangen oder so, wenn man das jetzt

00:24:49.200 --> 00:24:51.160
anguckt, der meinte so, ja, dann hat man bei den ganzen

00:24:51.160 --> 00:24:53.260
modernen Libraries heutzutage, dann hast du da

00:24:53.260 --> 00:24:55.240
irgendwie Funktionen und da hast

00:24:55.240 --> 00:24:57.020
du pro Zeile

00:24:57.020 --> 00:24:59.200
einen Parameter, weil da kommt immer

00:24:59.200 --> 00:25:00.980
der Name des Parameters, dann

00:25:00.980 --> 00:25:02.440
kommt halt die Typannotation,

00:25:03.240 --> 00:25:05.320
die einem nicht viel sagt und dann kommt nochmal ein Kommentar,

00:25:05.420 --> 00:25:07.120
der erklärt, was die Typannotation einem eigentlich

00:25:07.120 --> 00:25:09.160
sagen will und das dann so

00:25:09.160 --> 00:25:11.060
untereinander. Dann meinte er so, das erinnert mich total an

00:25:11.060 --> 00:25:13.180
C-Code aus den 80ern, ich weiß nicht,

00:25:13.260 --> 00:25:14.300
Ich mag das nicht.

00:25:14.860 --> 00:25:15.620
Das ist nicht Python.

00:25:16.260 --> 00:25:18.120
Ja, aber

00:25:18.120 --> 00:25:20.400
dieses Argument höre ich auch häufig, wenn man

00:25:20.400 --> 00:25:21.260
jetzt so bei den Alten,

00:25:21.940 --> 00:25:24.440
zum Beispiel übernächste Woche wieder

00:25:24.440 --> 00:25:25.640
oder als nächstes, ich weiß nicht.

00:25:26.860 --> 00:25:28.620
Auch hier aufs Python-User.

00:25:29.040 --> 00:25:29.580
Und das nächste, nächste Mittwoch.

00:25:29.880 --> 00:25:31.000
Das nächste Woche, ja.

00:25:31.960 --> 00:25:33.740
Genau, gehen. Da gibt es dann die

00:25:33.740 --> 00:25:35.940
alteingesessenen,

00:25:36.360 --> 00:25:37.700
die sagen auch immer so,

00:25:37.820 --> 00:25:40.520
immer nur Aks, Quaks, Sternchen, Sternchen.

00:25:40.520 --> 00:25:41.660
Nein, das nicht, aber

00:25:41.660 --> 00:25:43.960
Jaja, aber das ist schon so ein Punkt,

00:25:44.040 --> 00:25:45.080
mit dem viele Probleme haben, ja.

00:25:45.620 --> 00:25:47.780
Ich kenne genug Python, dass ich den Witz

00:25:47.780 --> 00:25:49.160
mit Aks-Quaks verstanden habe.

00:25:50.460 --> 00:25:51.980
Da gehörst du schon

00:25:51.980 --> 00:25:52.800
zu den Oberlehrern.

00:25:54.400 --> 00:25:55.480
Ja, also gut, also

00:25:55.480 --> 00:25:57.600
ich

00:25:57.600 --> 00:25:59.780
bin immer sehr kritisch,

00:25:59.780 --> 00:26:01.540
wenn es darum geht, dass man

00:26:01.540 --> 00:26:03.420
die Ästhetik bewertet, weil

00:26:03.420 --> 00:26:05.740
ich schreibe sehr viel in Rust. Rust ist

00:26:05.740 --> 00:26:07.540
eine sehr unästhetische Sprache. Du hast

00:26:07.540 --> 00:26:09.580
quasi, hey, wie viel Syntax

00:26:09.580 --> 00:26:11.560
kann eine Programmiersprache vertragen? Und Rust sagt,

00:26:11.640 --> 00:26:13.220
Ja, also her damit.

00:26:14.240 --> 00:26:15.580
Aber dafür ist mir halt

00:26:15.580 --> 00:26:17.800
zu jedem Zeitpunkt absolut

00:26:17.800 --> 00:26:19.120
hundertprozentig klar, was passiert.

00:26:19.400 --> 00:26:21.060
Und das ist halt auch ein Vorteil,

00:26:21.280 --> 00:26:23.660
den man nicht leugnen kann. Gerade wenn man in Teams

00:26:23.660 --> 00:26:25.260
arbeitet. Und da nehme ich halt die paar

00:26:25.260 --> 00:26:26.760
Annotationen, die ich da habe, einfach hin.

00:26:28.300 --> 00:26:33.440
irgendwas hat jetzt da geblinkt, ich bin kurz rausgekommen.

00:26:34.640 --> 00:26:35.660
Und verstehe zumindest,

00:26:35.660 --> 00:26:37.060
was passiert. Und ich muss ganz ehrlich sagen,

00:26:37.320 --> 00:26:39.120
was ich rein jetzt sehe von dem, was

00:26:39.120 --> 00:26:42.100
wie Python

00:26:42.100 --> 00:26:43.380
Typings umsetzt,

00:26:44.560 --> 00:26:46.420
ist das eh sehr

00:26:46.420 --> 00:26:48.240
minimalistisch. Also da kann man sich noch

00:26:48.240 --> 00:26:50.300
weit, weit mehr verausgaben. Also ich finde das gar nicht

00:26:50.300 --> 00:26:52.080
einmal so hässlich.

00:26:53.480 --> 00:26:54.540
Ja, ich finde

00:26:54.540 --> 00:26:56.480
das Problem ist halt, dass

00:26:56.480 --> 00:26:58.480
diese Typsysteme

00:26:58.480 --> 00:27:00.220
oft zu weit getrieben werden.

00:27:00.660 --> 00:27:02.180
Und das treibt dann Blüten.

00:27:02.180 --> 00:27:04.280
Ja, also für alles und jedes und nochmal die letzte.

00:27:04.380 --> 00:27:06.380
Genau, für alles und jedes. Und das muss dann alles ein benannter

00:27:06.380 --> 00:27:08.260
Typ sein und das geht dann,

00:27:08.840 --> 00:27:13.080
Also ich habe hier ein Beispiel aus der Apple-Dokumentation.

00:27:13.200 --> 00:27:14.600
Da gibt es einen Typen, der heißt

00:27:14.600 --> 00:27:16.760
CN Label Contact Relation Younger Cousin,

00:27:16.840 --> 00:27:18.840
Mother, Siblings, Daughter or Father, Sisters, Daughter.

00:27:19.480 --> 00:27:20.240
Das ist ein Typ.

00:27:20.340 --> 00:27:20.780
Wunderschön.

00:27:20.800 --> 00:27:22.760
Ja, ob man den jetzt braucht oder nicht.

00:27:23.240 --> 00:27:28.500
Auf der anderen Seite hier ein Beispiel aus der .NET-Bibliothek.

00:27:28.640 --> 00:27:30.140
Die Links sind dann alle in den Show Notes.

00:27:30.640 --> 00:27:31.920
Da gibt es eine Methode, die heißt Run.

00:27:32.580 --> 00:27:34.560
Die hat 30 Argumente.

00:27:35.100 --> 00:27:37.780
31, das erste ist ein Object, das heißt Makro.

00:27:37.860 --> 00:27:39.580
Das zweite ist ein Object, das heißt Arc 1.

00:27:40.420 --> 00:27:42.240
Das dritte ist ein Object, das heißt Arc 2.

00:27:42.400 --> 00:27:43.720
Und so geht es weiter bis Arc 30.

00:27:45.040 --> 00:27:45.480
Grandios.

00:27:45.520 --> 00:27:46.560
Da bringen mir die Typen nichts.

00:27:46.920 --> 00:27:50.680
Da sagen mir die Typen nicht, was das macht.

00:27:50.800 --> 00:27:52.080
Und zwar in beide Richtungen nicht.

00:27:52.560 --> 00:27:54.660
Und es gibt halt da diese Fetischisten, die sagen,

00:27:54.740 --> 00:27:56.880
du musst aber überall benannte Typen drin haben

00:27:56.880 --> 00:27:59.080
und du musst das Typsystem vollständig aufbauen.

00:27:59.080 --> 00:28:00.930
ausnutzen. Und

00:28:00.930 --> 00:28:03.130
das geht mir genauso auf den Senkel wie die alten Herren,

00:28:03.650 --> 00:28:04.530
die dann sagen, nein,

00:28:05.350 --> 00:28:07.270
Typ-Annotationen ist ekelhaft

00:28:07.270 --> 00:28:08.510
und hässlich und wie in den 80ern.

00:28:09.050 --> 00:28:10.910
Irgendwo in der Mitte ist dieses Maß.

00:28:12.490 --> 00:28:13.290
Du hast mich gerade

00:28:13.290 --> 00:28:15.130
an etwas Wunderbares erinnert. Ich bin ja

00:28:15.130 --> 00:28:17.370
in einer Java-Welt

00:28:17.370 --> 00:28:18.450
groß geworden.

00:28:19.690 --> 00:28:21.150
Und habe gelitten dort.

00:28:21.550 --> 00:28:21.950
Ich auch.

00:28:24.490 --> 00:28:25.370
Ich komme aus der

00:28:25.370 --> 00:28:27.230
Nähe von Linz und direkt

00:28:27.230 --> 00:28:33.410
also auf dem anderen Bergerl gegenüber, wohnt einer der Erfinder vom Spring-Framework.

00:28:33.770 --> 00:28:36.470
Also wir kennen uns, unsere Kinder gehen gemeinsam in die Schule und solche Sachen.

00:28:37.010 --> 00:28:44.610
Und da gibt es eine Klasse, das ist die Has this type pattern tried to sneak in some generic or parameterized type pattern matching stuff anywhere visitor.

00:28:45.410 --> 00:28:47.110
Und das ist fantastisch.

00:28:47.850 --> 00:28:54.190
Also bei uns in der Firma haben die Java-Developer diese Weißkin-Monitore,

00:28:54.190 --> 00:28:57.570
aber nicht, dass sie irgendwie dort mehrere Fenster nebeneinander hinkriegen,

00:28:57.670 --> 00:29:02.170
sondern ich sage immer, das ist, damit sie die Klassennamen ohne Zeilenhundbruch durchstehen können.

00:29:03.830 --> 00:29:06.110
Und das ist natürlich, das ist Mumpitz, das ist ganz klar.

00:29:06.430 --> 00:29:10.130
Ich denke, man muss die ganzen Sachen immer ein bisschen pragmatischer sehen

00:29:10.130 --> 00:29:15.450
und halt auch einen richtigen Nutzen oder wissen, welchen Nutzen man daraus zieht.

00:29:16.070 --> 00:29:18.090
Das gilt für alles in der Softwareentwicklung meiner Meinung nach.

00:29:19.230 --> 00:29:20.290
Das ist der Anzug.

00:29:21.390 --> 00:29:23.430
Genau. Was ich am liebsten habe zum Beispiel,

00:29:23.670 --> 00:29:25.130
also ich schreibe immer noch sehr, sehr viel

00:29:25.130 --> 00:29:27.130
Node und wenn ich starte damit,

00:29:27.130 --> 00:29:29.270
dann habe ich

00:29:29.270 --> 00:29:30.990
einmal keine Typen zu Beginn, weil ich ja selbst

00:29:30.990 --> 00:29:32.530
nicht weiß, wie mein Software am Ende ausschaut.

00:29:32.890 --> 00:29:35.170
Aber wenn ich dann fertig bin, wenn ich dann ein paar Funktionen extrahiert

00:29:35.170 --> 00:29:37.190
habe, dann lasse ich mir ein paar Typen

00:29:37.190 --> 00:29:39.010
einführen, einfach nur, dass ich festgelegt habe,

00:29:39.630 --> 00:29:41.130
was ich hier an dieser Stelle

00:29:41.130 --> 00:29:43.130
erwarte, damit, wenn ich zurückgehe

00:29:43.130 --> 00:29:44.850
oder wer von meinen Kolleginnen oder Kollegen

00:29:44.850 --> 00:29:47.270
zurückgeht, auch weiß,

00:29:47.410 --> 00:29:48.650
was dort zu erwarten war.

00:29:48.870 --> 00:29:50.950
Und um das geht es eigentlich. Und gerade in

00:29:50.950 --> 00:29:52.810
Types gibt. Also gerade auch in meinem Buch gibt es

00:29:52.810 --> 00:29:53.950
ein paar Beispiele drinnen.

00:29:55.090 --> 00:29:57.090
Da kann man sich schon richtig, richtig vorausgucken.

00:29:57.190 --> 00:29:58.890
Da gibt es irrsinnig mächtige Werkzeuge

00:29:58.890 --> 00:30:00.530
wie String Template Literal Types oder

00:30:00.530 --> 00:30:02.350
Tappel Types, Variadic Tappel Types.

00:30:03.230 --> 00:30:04.850
Das sind Dinge, wo ich mir denke,

00:30:05.670 --> 00:30:07.050
Wahnsinn, dass das überhaupt geht.

00:30:07.330 --> 00:30:09.090
Also beeindruckend technisch, dass das geht.

00:30:09.790 --> 00:30:10.810
Aber die Use Cases

00:30:10.810 --> 00:30:12.950
dafür sind halt stark limitiert und man muss wirklich überlegen,

00:30:13.070 --> 00:30:14.650
ob das dafür steht. Und ich habe dort

00:30:14.650 --> 00:30:16.810
drei Lektionen, wo wir

00:30:16.810 --> 00:30:19.050
ein funktionales

00:30:19.050 --> 00:30:20.590
Programmiertool wie

00:30:20.590 --> 00:30:24.850
wie Currying, versuchen, auf drei sehr, sehr komplexe Orten umzusetzen und zu sagen,

00:30:24.990 --> 00:30:29.790
aber überleg dir, ob diese Typen jetzt das gerechtfertigen, was du da als Funktion schreibst,

00:30:30.130 --> 00:30:33.090
oder ob du nicht lieber eine Funktion nimmst, die viel, viel weniger kann,

00:30:33.690 --> 00:30:38.270
aber genauso einfach zu verwenden ist und die einfach zu typisieren ist,

00:30:38.270 --> 00:30:41.910
mit der du besser die Typinformationen rauskriegst.

00:30:42.630 --> 00:30:44.090
Und das stelle ich dann auch so zur Diskussion.

00:30:44.330 --> 00:30:50.050
Also man muss halt immer abwägen können, wie rechtfertigst du den Einsatz dieses Werkzeugs

00:30:50.050 --> 00:30:51.370
und wie weit treibst du das?

00:30:52.090 --> 00:30:54.330
Ja, ich glaube, das ist tatsächlich gar nicht so einfach rauszufinden.

00:30:55.050 --> 00:30:55.710
Ja, und

00:30:55.710 --> 00:30:58.170
ich glaube aber, dass da noch ein anderes Problem

00:30:58.170 --> 00:31:00.150
dahinter ist und ich bin sehr froh,

00:31:00.230 --> 00:31:02.070
Stefan, dass du da gesagt hast, dass du

00:31:02.070 --> 00:31:04.130
gegen Tests bist

00:31:04.130 --> 00:31:05.950
oder gegen große Testcoverage

00:31:05.950 --> 00:31:08.130
und du hast jetzt gerade eben so ein bisschen deinen Ansatz

00:31:08.130 --> 00:31:10.070
beschrieben, wie du Programme schreibst

00:31:10.070 --> 00:31:12.110
und du hast was gesagt,

00:31:12.170 --> 00:31:13.490
was meiner Meinung nach ganz wichtig ist.

00:31:14.010 --> 00:31:16.070
Du hast gesagt, du fängst an, ein Programm zu schreiben und weißt

00:31:16.070 --> 00:31:17.490
noch nicht, wie es am Ende ausschauen wird.

00:31:18.470 --> 00:31:19.570
Und das

00:31:19.570 --> 00:31:21.930
geht mir genauso. Und das ist einer

00:31:21.930 --> 00:31:23.110
der Gründe, warum ich

00:31:23.110 --> 00:31:25.970
Python

00:31:25.970 --> 00:31:27.850
mag, weil mir das die Freiheit

00:31:27.850 --> 00:31:30.010
gibt, da so explorativ rumzugehen,

00:31:30.170 --> 00:31:31.990
ohne mir groß Gedanken machen

00:31:31.990 --> 00:31:33.950
zu müssen, wie es denn jetzt sauber zusammenpasst.

00:31:34.610 --> 00:31:36.230
Und ich glaube, dass das ein Programmierstil

00:31:36.230 --> 00:31:37.470
ist. Ich nenne das

00:31:37.470 --> 00:31:39.770
exploratives Programmieren. Ich muss so ein bisschen

00:31:39.770 --> 00:31:41.750
diesen Space erkunden, muss so ein bisschen sehen,

00:31:42.290 --> 00:31:44.050
was kann ich, was schaffe ich, was mache

00:31:44.050 --> 00:31:45.950
ich. Und das ist halt

00:31:45.950 --> 00:31:47.890
mein Stil. Ich gehe da rein und sage, jetzt machen wir

00:31:47.890 --> 00:31:49.910
erstmal irgendwas. Es gibt aber auch Leute,

00:31:50.050 --> 00:31:52.190
die da vielleicht mathematischer

00:31:52.190 --> 00:31:53.850
rangehen und die sagen, okay, ich habe hier

00:31:53.850 --> 00:31:55.830
einen Plan und eigentlich auf dem Papier habe ich es ja

00:31:55.830 --> 00:31:56.510
schon hingeschrieben,

00:31:57.550 --> 00:31:59.910
dann kann ich auch die Tests zuerst schreiben, weil ich weiß

00:31:59.910 --> 00:32:02.130
ja schon, was das machen soll. Ich weiß ja schon, wie es am Ende ausschaut.

00:32:02.630 --> 00:32:04.010
Oder ich kann gleich die richtigen Typen

00:32:04.010 --> 00:32:05.950
reinschreiben. Ja, da muss man sich ja das Akronym

00:32:05.950 --> 00:32:08.390
ändern und einfach Type-Driven-Development

00:32:08.390 --> 00:32:09.630
von einem neuen

00:32:09.630 --> 00:32:10.530
Stand starten.

00:32:11.730 --> 00:32:13.390
Und da

00:32:13.390 --> 00:32:15.470
ja, das

00:32:15.470 --> 00:32:17.550
sind, glaube ich, einfach zwei verschiedene

00:32:17.550 --> 00:32:19.570
Arten zu programmieren, die eben

00:32:19.570 --> 00:32:21.850
verschiedene Dinge eher bevorzugen.

00:32:23.030 --> 00:32:23.290
Es

00:32:23.290 --> 00:32:25.670
ist tatsächlich, glaube ich, auch ein bisschen von der Sprache

00:32:25.670 --> 00:32:27.570
abhängig, weil, also ich glaube,

00:32:27.630 --> 00:32:29.550
Python und JavaScript unterstützen ja diese Art

00:32:29.550 --> 00:32:31.370
des explorativen Programmierens sehr, sehr stark.

00:32:31.470 --> 00:32:33.510
Einfach eben in dem sie die Typen auch

00:32:33.510 --> 00:32:35.430
entfernen. Also du kannst sie wirklich einfach mal

00:32:35.430 --> 00:32:37.150
herumprobieren und schauen, was rauskommt.

00:32:37.630 --> 00:32:39.650
Und schauen, wie weit

00:32:39.650 --> 00:32:41.170
du mit deinen Ideen kommst.

00:32:42.350 --> 00:32:43.370
Was ich spannend finde,

00:32:43.530 --> 00:32:45.570
also ich bin jetzt seit einigen Jahren auch sehr,

00:32:45.710 --> 00:32:47.330
sehr stark im Lasten drin, ich habe das jetzt schon erwähnt, und sorry,

00:32:47.430 --> 00:32:49.090
Das ist der klassische Rust-Nutzer.

00:32:49.230 --> 00:32:51.170
Nicht, dass ich ständig sage, dass er Rust verwendet,

00:32:51.390 --> 00:32:52.970
aber es ist halt wirklich so.

00:32:53.270 --> 00:32:54.590
Die Sprache macht einiges sehr, sehr richtig.

00:32:54.750 --> 00:32:58.890
Du hast in Rust eine sehr stark typisierte Programmiersprache

00:32:58.890 --> 00:33:00.850
mit einem fantastischen Typsystem.

00:33:01.010 --> 00:33:04.790
Das ist grandios, dass das so funktioniert, wie es funktioniert.

00:33:04.910 --> 00:33:06.430
Das heißt, du kannst dir gar nicht leisten,

00:33:06.510 --> 00:33:07.330
dass du einfach nur mal schaust,

00:33:08.690 --> 00:33:13.390
wo kommst du mit deinen Wertebereichen überhaupt am Ende hin.

00:33:13.390 --> 00:33:17.170
Aber trotzdem schafft es Rust, dass du explorativ arbeiten kannst,

00:33:17.250 --> 00:33:21.570
weil einfach die Mittel, die zur Verfügung gestellt werden, so zugänglich sein können,

00:33:21.670 --> 00:33:25.650
weil die Typen, die von Haus aus schon drinnen sind, so entgegenkommen sind.

00:33:25.770 --> 00:33:28.210
Das heißt, du kommst mit ein paar Basistypen aus der Standardbibliothek

00:33:28.210 --> 00:33:31.110
und den üblichen Wertebereichen schon sehr, sehr weit,

00:33:31.110 --> 00:33:38.370
bevor du dir selbst deine eigenen Strukturen und Interfaces, nenne ich es jetzt einmal,

00:33:38.810 --> 00:33:40.210
heißen anders, überlegen musst.

00:33:40.850 --> 00:33:41.970
Und das ist sehr, sehr spannend.

00:33:42.250 --> 00:33:44.070
Es ist aber trotzdem ein anderer Wert des Programmierens.

00:33:44.270 --> 00:33:49.250
Also das Endresultat schaut auch dann anders aus.

00:33:49.270 --> 00:33:53.210
Also ich mag das aber auch gerne, so Models oder so Dataclasses irgendwie zu bauen

00:33:53.210 --> 00:33:55.230
und dann zu gucken, hey, was sind das denn überhaupt für Objekte

00:33:55.230 --> 00:33:57.290
und dir halt dann direkt zur Annotation zu verwenden.

00:33:57.430 --> 00:34:00.170
Das ist so strukturell sehr klar.

00:34:01.230 --> 00:34:02.490
Nein, es schließt sich auch nicht aus.

00:34:02.730 --> 00:34:09.210
Also ich denke mir, die Gefahr liegt wahrscheinlich,

00:34:09.330 --> 00:34:12.010
dass man sich auf eines komplett verschreibt.

00:34:13.170 --> 00:34:15.910
Auch das, was der Johannes wieder gesagt hat, ganz richtig ist,

00:34:16.790 --> 00:34:21.250
es ist am Ende des Tages ein Werkzeug und es muss irgendeinen Job erfüllen.

00:34:22.530 --> 00:34:25.350
Und wenn das gut funktioniert, dass du dir vorher Gedanken darüber machst,

00:34:25.430 --> 00:34:28.610
welche Daten du benötigst, dann ist das absolut legitim meiner Meinung nach.

00:34:28.950 --> 00:34:32.690
Also ich finde die gerade so angenehm.

00:34:33.050 --> 00:34:35.550
Wichtig ist, dass die Sprache mit der du arbeitest, das unterstützt.

00:34:36.350 --> 00:34:37.610
Ja, ich glaube auch eben.

00:34:39.270 --> 00:34:41.070
Aber ich meine, das hat natürlich einen Preis,

00:34:41.210 --> 00:34:44.730
weil es halt zusätzliche Komplexität unter Umständen halt auch einführt

00:34:44.730 --> 00:34:46.630
und es dann halt vielleicht auch unzugänglicher macht.

00:34:46.790 --> 00:34:49.290
Also worauf ich eigentlich hinaus will ist,

00:34:50.630 --> 00:34:54.730
naja, je nach Use Case kann es halt unterschiedlich nützlich sein.

00:34:54.910 --> 00:34:57.310
Also wenn man halt zum Beispiel eben in einem Team

00:34:57.310 --> 00:34:59.210
an einer großen Software schreibt,

00:34:59.330 --> 00:35:00.950
dann kann es halt sein, dass es sehr viel bringt,

00:35:01.470 --> 00:35:04.870
auch irgendwie möglichst viele Hürden zu errichten,

00:35:05.190 --> 00:35:06.610
bevor irgendwie Code...

00:35:06.610 --> 00:35:08.410
Du willst quasi gar nicht, dass die Entwickler irgendwas machen.

00:35:08.410 --> 00:35:32.210
Ja, das ist leider halt eine Strategie, das ist schwer zu unterscheiden von irgendwie, man versucht Fehler zu vermeiden, bevor sie dann produktiv gehen, zu bloß nicht deployen, was dann halt auch viele Leute machen, was halt irgendwie auch blöde Konsequenzen hat unter Umständen dann, weil also viele Sachen, also man hat dann zum Beispiel nicht nur ein Staging-System, sondern noch so drei andere oder vier andere und führt immer mehr hinzu, sodass man bloß nicht nach Produktionen deployen muss.

00:35:32.210 --> 00:35:37.950
Ich habe zwei Abteilungen bei uns kennengelernt, die haben einen Employment-Release-Zyklus so alle sechs Monate.

00:35:38.230 --> 00:35:45.590
Ja, genau. In den sechs Monaten passiert halt auch nichts, aber es ist halt vielleicht auch irgendwie ein Konflikt mit anderen Zielen.

00:35:46.470 --> 00:35:50.470
Hast du etwa diesen Artikel über Move Fast and Break Things gelesen, der kürzlich rausgekommen ist?

00:35:50.470 --> 00:35:50.970
Ja, genau.

00:35:52.450 --> 00:35:53.070
Ja, richtig.

00:35:54.930 --> 00:35:56.850
Genau, also an der Stelle macht es ja

00:35:56.850 --> 00:35:58.890
vielleicht, wenn man in so einer Situation ist,

00:35:59.350 --> 00:36:00.230
sehr viel Sinn, da

00:36:00.230 --> 00:36:02.870
von den Leuten zu verlangen, dass sie sich erst Gedanken

00:36:02.870 --> 00:36:04.890
machen und dass halt man versucht, möglichst viele

00:36:04.890 --> 00:36:06.810
Fehler zu fangen, bevor

00:36:06.810 --> 00:36:08.870
sie halt in der Produktion aufschlagen,

00:36:08.990 --> 00:36:10.710
weil da ist es halt viel teurer, sie halt zu

00:36:10.710 --> 00:36:12.350
entfernen. Aber

00:36:12.350 --> 00:36:14.610
es kann halt total anders sein, wenn jetzt jemand

00:36:14.610 --> 00:36:16.630
zum Beispiel, und das ist halt eine der Stärken

00:36:16.630 --> 00:36:18.750
bei Python, bei JavaScript

00:36:18.750 --> 00:36:20.530
auch ein bisschen anders,

00:36:21.230 --> 00:36:22.630
dass

00:36:22.630 --> 00:36:24.630
es halt vor allen Dingen auch von Leuten benutzt wird, die

00:36:24.630 --> 00:36:26.190
sich selber gar nicht als professionelle

00:36:26.190 --> 00:36:28.550
Programmierer sehen würden, sondern die eher sagen würden,

00:36:28.650 --> 00:36:29.710
naja, ich bin eigentlich eher so

00:36:29.710 --> 00:36:32.870
Data Scientist oder ein Analyst

00:36:32.870 --> 00:36:34.290
oder sowas oder halt

00:36:34.290 --> 00:36:36.630
irgendwie jemand, der irgendwie, keine Ahnung,

00:36:36.710 --> 00:36:38.530
Roboter irgendwie dazu bringt, irgendwie

00:36:38.530 --> 00:36:39.970
lustige Dinge zu machen oder sowas.

00:36:40.870 --> 00:36:42.050
Oder Teilchenbeschleuniger.

00:36:42.450 --> 00:36:44.410
Oder Teilchenbeschleuniger, also solche Sachen, genau.

00:36:44.990 --> 00:36:46.590
Und ich will gar nicht jetzt irgendwie

00:36:46.590 --> 00:36:48.450
Typtheorie

00:36:48.450 --> 00:36:50.550
verstehen oder irgendwie

00:36:50.550 --> 00:36:52.570
keine Ahnung, auch Unitests

00:36:52.570 --> 00:36:54.550
und da sind wir auch bei einem Ding, wo die

00:36:54.550 --> 00:36:56.510
Sachen so ein bisschen ähnlich sind. Also ich dachte auch

00:36:56.510 --> 00:36:57.410
lange Zeit irgendwie

00:36:57.410 --> 00:37:00.290
Unitests sind was ganz anderes

00:37:00.290 --> 00:37:01.950
und Typisierung

00:37:01.950 --> 00:37:03.870
ist ein

00:37:03.870 --> 00:37:06.210
anderes Ende von einem Spektrum und ich bin eher so

00:37:06.210 --> 00:37:08.250
Teamtest, aber inzwischen denke ich so, naja,

00:37:08.310 --> 00:37:10.590
das ist schon relativ ähnlich auch. Ich meine auch Unitesting

00:37:10.590 --> 00:37:12.150
ist halt so eine Sache, die man sich erst

00:37:12.150 --> 00:37:14.510
irgendwie erschließen muss und für manche Leute

00:37:14.510 --> 00:37:16.350
macht das einfach, wenn man halt irgendwie

00:37:16.350 --> 00:37:18.310
so in einem Jupyter-Notebook Sachen macht.

00:37:19.570 --> 00:37:19.830
Ja,

00:37:20.230 --> 00:37:22.250
manchmal macht es schon Sinn, das zu testen, aber für viele

00:37:22.250 --> 00:37:24.050
Leute ist es auch nicht, lohnt es sich, weiß ich nicht,

00:37:24.110 --> 00:37:26.490
ob es sich wirklich lohnt, da so tief einzusteigen.

00:37:27.590 --> 00:37:28.350
Und, aber, ich meine,

00:37:28.430 --> 00:37:30.350
klar, wenn man jetzt große Software in einem Team

00:37:30.350 --> 00:37:32.310
entwickelt, dann, klar, hat man Tests und

00:37:32.310 --> 00:37:34.350
eine CI-Pipeline und weiß ich nicht,

00:37:34.450 --> 00:37:35.350
diesen ganzen Kram halt, ne?

00:37:36.190 --> 00:37:38.270
Ja, das Stichwort da ist

00:37:38.270 --> 00:37:40.270
doch Programming by Contract, oder? Und das

00:37:40.270 --> 00:37:42.210
ist halt eine Möglichkeit, so einen Contract

00:37:42.210 --> 00:37:44.250
zu schreiben. Aber, also

00:37:44.250 --> 00:37:46.090
ich bin da in so einem Zwiespalt, ja, einerseits

00:37:46.090 --> 00:37:48.130
bin ich total genervt von solchen Typsystemen, die dann

00:37:48.130 --> 00:37:49.490
sehr präzise sind und die dann

00:37:49.490 --> 00:37:52.110
ich habe auch, ich bin auch mit Java aufgewachsen

00:37:52.110 --> 00:37:53.750
Stefan, also ich zähle deinen Schmerz

00:37:53.750 --> 00:37:55.410
und dann

00:37:55.410 --> 00:37:58.050
wirkt man sich ab und macht

00:37:58.050 --> 00:37:59.950
ein Pair aus Int und

00:37:59.950 --> 00:38:01.950
String und dann weißt du aber nicht, wie du an den

00:38:01.950 --> 00:38:04.030
zweiten dran kommst und ach, das ist

00:38:04.030 --> 00:38:06.030
alles ganz schön. Aber auf

00:38:06.030 --> 00:38:08.110
der anderen Seite gibt es

00:38:08.110 --> 00:38:09.990
nicht die Möglichkeit zu sagen, ganz

00:38:09.990 --> 00:38:11.930
triviale Sachen zu sagen. Zum Beispiel hier

00:38:11.930 --> 00:38:13.670
muss eine Zahl rauskommen, die immer größer ist als 0

00:38:13.670 --> 00:38:15.930
oder immer kleiner als 0. Größer als 0 geht

00:38:15.930 --> 00:38:17.930
ja tatsächlich noch, aber kleiner als 0

00:38:17.930 --> 00:38:19.730
kannst du nicht sagen. Du kannst nicht sagen, hier

00:38:19.730 --> 00:38:21.590
muss was rauskommen, was zwischen 0 und 1 liegt.

00:38:22.310 --> 00:38:23.710
Und das ist irgendwie so

00:38:23.710 --> 00:38:25.170
eine weirde Sache.

00:38:25.890 --> 00:38:27.630
Ich bin da so im Zwiespalt. Ich hätte gerne

00:38:27.630 --> 00:38:29.750
keine Typsysteme, aber wenn ich Typsysteme hätte,

00:38:29.810 --> 00:38:31.950
hätte ich gerne so welche, die so exakt sind,

00:38:32.950 --> 00:38:34.170
dass ich sowas sagen kann.

00:38:34.230 --> 00:38:35.590
Und dass mir dann auch der Compiler sagen kann,

00:38:35.650 --> 00:38:37.950
Moment, hier rufst du eine Funktion aus mit einer Zahl,

00:38:38.070 --> 00:38:40.010
die zwischen 0 und 1 sein kann,

00:38:40.110 --> 00:38:41.830
aber die muss zwischen 0 und

00:38:41.830 --> 00:38:42.510
minus 1 sein.

00:38:42.950 --> 00:38:45.150
Nee, das ist nicht Validierung, sondern das ist

00:38:45.150 --> 00:38:47.270
Nee, das sind sogenannte Value-Types.

00:38:47.330 --> 00:38:49.050
Das kannst du auch in ein Typ-System reingießen,

00:38:49.110 --> 00:38:49.850
wenn du das möchtest.

00:38:50.690 --> 00:38:52.810
Das ist quasi keine Sprache.

00:38:53.210 --> 00:38:54.390
Ich glaube, ich habe eine mal gesehen.

00:38:54.490 --> 00:38:54.850
Eifel.

00:38:55.170 --> 00:38:56.070
Eifel, ja genau.

00:38:56.970 --> 00:38:59.630
Also grundsätzlich im funktionalen Programmierbereich

00:38:59.630 --> 00:39:01.290
hast du das relativ häufig.

00:39:01.290 --> 00:39:02.650
Ja, es gibt da so ein paar Erweiterungen.

00:39:03.910 --> 00:39:06.890
Aber ich würde mal annehmen,

00:39:07.030 --> 00:39:10.550
nicht in den populären oder weitverbreiteten Programmierungen.

00:39:10.550 --> 00:39:12.010
Nee, nicht in denen, die man benutzt irgendwo.

00:39:12.470 --> 00:39:13.750
Oder die man schon mal gehört hat.

00:39:14.810 --> 00:39:19.610
Aus einem ganz einfachen Grund, weil du halt unter den Wertebereichen von einer Zahl

00:39:19.610 --> 00:39:23.970
tatsächlich irgendwelche Bytes liegen, die von einer CPU ausgelesen werden.

00:39:25.690 --> 00:39:26.510
Ja, klar.

00:39:26.770 --> 00:39:31.350
Wenn dir das Typsystem das erlaubt, dass du dort irgendwas zwischen Minus 1 und Plus 1

00:39:31.350 --> 00:39:35.730
zum Beispiel definierst, oder mein Gott, eine ganze Zahl zwischen 25, was auch immer,

00:39:36.450 --> 00:39:39.030
dann schiebst du die Validierungen nur an eine andere Stelle.

00:39:40.970 --> 00:39:43.410
Ja gut, aber das machst du mit dem Typsystem generell, oder?

00:39:43.530 --> 00:39:45.330
Also ich meine, sobald der PipeScript-Compiler

00:39:45.330 --> 00:39:46.170
durch ist, ist er weg.

00:39:46.470 --> 00:39:48.430
Das ist sehr richtig, genau.

00:39:49.310 --> 00:39:51.690
Ich glaube, in Python genauso, wenn ich mich nicht täusche.

00:39:52.010 --> 00:39:52.530
Ja, generell.

00:39:52.930 --> 00:39:54.930
In Python sind die Annotationen erstmal gar nichts.

00:39:55.030 --> 00:39:57.130
Genau, das ist in Python auch so leicht anders.

00:39:57.370 --> 00:39:58.290
Das wissen auch viele Leute.

00:39:58.370 --> 00:40:01.250
Das ist halt, wenn man zu den praktischen Dingen kommt,

00:40:01.310 --> 00:40:03.150
die halt damit problematisch sind, also ich bin ja häufiger

00:40:03.150 --> 00:40:04.970
auch irgendwie in unterschiedlichen

00:40:04.970 --> 00:40:07.570
Firmenkontexten da so unterwegs

00:40:07.570 --> 00:40:09.350
und das,

00:40:09.350 --> 00:40:10.930
was ich in letzter Zeit halt häufig sehe,

00:40:11.150 --> 00:40:13.030
ist halt sowas wie Leute

00:40:13.030 --> 00:40:14.930
annotieren halt irgendwie ganz viel,

00:40:15.830 --> 00:40:16.310
aber

00:40:16.310 --> 00:40:19.090
sie haben keinen statischen

00:40:19.090 --> 00:40:20.990
Type-Checker, der da drüber laufen würde. Und in Python

00:40:20.990 --> 00:40:23.150
ist halt auch keiner eingebaut, was vielleicht auch nicht so gut

00:40:23.150 --> 00:40:24.970
ist. Und man müsste da

00:40:24.970 --> 00:40:27.090
und dann mache ich dann sowas wie

00:40:27.090 --> 00:40:29.070
ich lasse mal MyPy drüber laufen und die Leute

00:40:29.070 --> 00:40:31.050
verwenden alle TypeDict und sowas und denken

00:40:31.050 --> 00:40:33.110
halt, ja, das überprüft jetzt, ob meine ganzen

00:40:33.110 --> 00:40:33.810
Werte da so

00:40:33.810 --> 00:40:36.830
meine ganzen Werte in dem Dict halt so

00:40:36.830 --> 00:40:39.150
den richtigen Typ haben

00:40:39.150 --> 00:40:41.210
und so. Und Python selber

00:40:41.210 --> 00:40:42.970
macht da gar nichts. Das überprüft überhaupt nichts.

00:40:43.030 --> 00:40:45.110
es ignoriert die Annotationen einfach.

00:40:45.390 --> 00:40:46.870
Ich lasse dann MyPy drüberlaufen und kriege dann so

00:40:46.870 --> 00:40:48.910
400 Fehler. Und dann denke ich mir so, okay,

00:40:49.190 --> 00:40:50.990
ja, also du hast da schön deine Annahmen

00:40:50.990 --> 00:40:52.950
darüber, wie die ganzen Typen aussehen, dokumentiert, aber die

00:40:52.950 --> 00:40:54.850
sind halt leider alle falsch. Das stimmt überhaupt

00:40:54.850 --> 00:40:56.970
gar nicht. Und ja, da ist

00:40:56.970 --> 00:40:58.830
dann, denkt man sich, warum hat man sich denn überhaupt die Mühe gemacht?

00:40:59.030 --> 00:41:00.950
Also es ist halt irgendwie...

00:41:00.950 --> 00:41:02.790
Ja, wie ist denn der Zustand

00:41:02.790 --> 00:41:05.010
der Entwicklungsumgebungen in Python?

00:41:06.810 --> 00:41:07.490
Kommt drauf an.

00:41:07.630 --> 00:41:09.110
Also auch die hängen halt daran, ob du

00:41:09.110 --> 00:41:10.870
MyPy zum Beispiel

00:41:10.870 --> 00:41:12.530
als Static Type Shaper Extension

00:41:12.530 --> 00:41:13.990
richtig konfiguriert hast.

00:41:14.770 --> 00:41:16.490
Und ob dann auch MyPi

00:41:16.490 --> 00:41:18.370
die Stubs halt lesen kann,

00:41:18.530 --> 00:41:20.510
die halt notwendig sind oder halt auch nicht.

00:41:21.110 --> 00:41:21.770
Die müssen halt alle dann...

00:41:21.770 --> 00:41:23.810
Aber viele IDEs behandeln das doch auch selber schon.

00:41:23.810 --> 00:41:25.130
Ja, ja, genau.

00:41:25.350 --> 00:41:27.470
Da gibt es ja auch dann, ich weiß gar nicht jetzt,

00:41:27.770 --> 00:41:28.930
was bei VS Code

00:41:28.930 --> 00:41:30.690
dann normalerweise verwendet wird.

00:41:30.710 --> 00:41:31.750
MyPi ist eine Extension.

00:41:32.470 --> 00:41:34.790
Ja, aber ich meine, wenn jetzt zum Beispiel einfach nur das...

00:41:34.790 --> 00:41:36.090
Also IntelliJ macht das selber.

00:41:36.310 --> 00:41:39.710
Ja, die haben einen proprietären, dann gibt es irgendwie MyPi, klar.

00:41:40.430 --> 00:41:42.070
Und es gibt halt noch PyRide

00:41:42.070 --> 00:41:44.950
und der Language-Server

00:41:44.950 --> 00:41:46.530
für Python, kann es sein,

00:41:46.610 --> 00:41:47.990
dass er selber von Microsoft

00:41:47.990 --> 00:41:49.710
in TypeScript geschrieben ist?

00:41:49.710 --> 00:41:52.710
Ja, es ist

00:41:52.710 --> 00:41:54.050
nämlich spannend, weil ich

00:41:54.050 --> 00:41:56.450
denke, TypeScript

00:41:56.450 --> 00:41:58.330
hat da einige richtige Entscheidungen getroffen

00:41:58.330 --> 00:41:59.030
auf dem Gebiet.

00:42:00.370 --> 00:42:01.890
Die ihr jetzt alle angesprochen habt,

00:42:01.950 --> 00:42:03.910
was kompliziert und was komplex

00:42:03.910 --> 00:42:05.170
in Python ist,

00:42:06.710 --> 00:42:08.370
nämlich, dass die Sprache

00:42:08.370 --> 00:42:09.370
dir zwar ein Typsystem

00:42:09.370 --> 00:42:11.330
anbietet, cool,

00:42:12.070 --> 00:42:13.630
aber eigentlich nichts damit machst, sondern du brauchst

00:42:13.630 --> 00:42:15.250
eh nur einen extra Typ-Checker und

00:42:15.250 --> 00:42:17.510
anscheinend wie bei den Package-Managern gibt es

00:42:17.510 --> 00:42:19.530
dort auch mehrere, wo du dir dann noch aussuchen

00:42:19.530 --> 00:42:21.430
kannst, welcher gefällt dir jetzt und

00:42:21.430 --> 00:42:23.430
welcher passt zu dir und so weiter

00:42:23.430 --> 00:42:25.570
und ich finde das grandios, dass es Auswahl gibt,

00:42:25.670 --> 00:42:27.450
keine Frage, aber es erhöht natürlich auch die

00:42:27.450 --> 00:42:29.290
Komplexität. Und TypeScript

00:42:29.290 --> 00:42:31.430
hat, TypeScript

00:42:31.430 --> 00:42:32.970
selbst ist ja eigentlich

00:42:32.970 --> 00:42:35.310
mehrere Dinge. Es ist zum einen einmal ein Typ-System,

00:42:35.530 --> 00:42:37.510
cool, also wie werden Typen geschrieben,

00:42:37.650 --> 00:42:39.770
definiert, wie sind sie im Zusammenhang.

00:42:40.090 --> 00:42:41.370
Es ist auch ein Typ-Checker dabei,

00:42:42.070 --> 00:42:44.710
also der TypeScript-Compiler

00:42:44.710 --> 00:42:46.590
TSC macht in erster Linie mal

00:42:46.590 --> 00:42:48.150
Type-Checking, aber

00:42:48.150 --> 00:42:50.650
kompiliert dann auch tatsächlich JavaScript-Code,

00:42:50.730 --> 00:42:52.390
den du ausführen kannst. Also es gibt so jetzt

00:42:52.390 --> 00:42:54.870
Proposals, dass du auch Typ-Annotationen

00:42:54.870 --> 00:42:56.810
irgendwann einmal in JavaScript schreiben können

00:42:56.810 --> 00:42:58.550
solltest, ähnlich wie in Python, wir sind dort einfach

00:42:58.550 --> 00:42:59.590
von der Runtime ignoriert,

00:43:00.390 --> 00:43:02.810
aber da sind wir noch nicht, also da kommen wir erst hin.

00:43:03.090 --> 00:43:04.210
Das heißt, du brauchst auch den Compiler.

00:43:04.350 --> 00:43:06.590
Das heißt, wir haben Typ-System, Typ-Checker, Compiler und noch auch

00:43:06.590 --> 00:43:08.530
ganz, ganz wichtig, eine Integration

00:43:08.530 --> 00:43:10.990
in Editoren und Entwicklungsumgebungen.

00:43:11.790 --> 00:43:16.470
Und das war eigentlich, also dieser gesamte Tooling-Aspekt rundherum,

00:43:16.470 --> 00:43:20.870
nicht nur das Typ-System anzubieten, sondern auch Werkzeuge anzubieten,

00:43:20.950 --> 00:43:24.850
dass du nachher zu validem JavaScript-Code kommst und du deine Fehler siehst

00:43:24.850 --> 00:43:28.410
und die Fehler auch sofort in deinem Editor und deiner IDE dargestellt werden,

00:43:29.390 --> 00:43:32.750
sind meiner Meinung nach genau die Punkte, die nachher auch den,

00:43:32.930 --> 00:43:39.850
unter Anführungszeichen, Ziegelszug von TypeScript auch zu verantworten gehabt haben.

00:43:40.650 --> 00:44:09.590
Weil ohne dem hast du halt nur die Hälfte der Dinge. Du brauchst halt irgendwie alles, damit du sauber entwickeln kannst. Und wenn ich mir denke, dass ich Visual Studio Code aufmache, wo TypeScript schon drinnen ist und ich mache irgendein JavaScript-File auf und es läuft im Hintergrund schon der TypeScript-Compiler und checkt meinen JavaScript-Code und versucht zu inferieren und zu verstehen, was ich schon geschrieben habe ohne einzige Typ-Annotation und ich kriege aus dem raus schon Autocomplete und die ersten Warnings,

00:44:09.590 --> 00:44:13.850
dass vielleicht irgendwas nicht ganz rund läuft und schief geht.

00:44:14.370 --> 00:44:15.470
Das ist so viel wert,

00:44:15.690 --> 00:44:17.610
ohne dass ich eine Zeile TypeScript schreibe,

00:44:18.050 --> 00:44:18.370
wo ich mir denke,

00:44:18.430 --> 00:44:20.970
ja, das ist eigentlich eine richtig gute Idee gewesen.

00:44:21.890 --> 00:44:23.410
Ja, absolut.

00:44:23.530 --> 00:44:25.150
Da kann Python sich, glaube ich,

00:44:25.170 --> 00:44:26.610
auch noch eine Scheibe abschneiden davon,

00:44:26.730 --> 00:44:29.310
weil da gibt es noch so ein paar Löcher.

00:44:29.710 --> 00:44:30.670
Also wenn ich jetzt sage,

00:44:31.110 --> 00:44:32.830
ich installiere PyCharm oder wie auch immer,

00:44:33.290 --> 00:44:33.810
welche Idee,

00:44:34.170 --> 00:44:36.910
und die kommt schon mit einem Typinterpreter

00:44:36.910 --> 00:44:37.930
oder einem TypeChecker mit,

00:44:38.550 --> 00:44:40.270
Das wäre natürlich göttlich nett, dass du einfach

00:44:40.270 --> 00:44:42.210
sagst, hey, du brauchst nicht mehr die Typernotation

00:44:42.210 --> 00:44:43.670
schreiben, aber die IDE

00:44:43.670 --> 00:44:46.130
hat irgendeinen Type-Checker schon

00:44:46.130 --> 00:44:48.290
per T-Fold drinnen. Wahrscheinlich schreiben sie ihn selbst,

00:44:48.390 --> 00:44:50.230
weil JetBrains schreibt das irgendwie selbst.

00:44:50.350 --> 00:44:50.630
Haben sie.

00:44:51.890 --> 00:44:55.090
Der von JetBrains ist

00:44:55.090 --> 00:44:58.210
der ist super gut.

00:44:59.070 --> 00:45:00.230
Das ist einer der Gründe, warum

00:45:00.230 --> 00:45:02.010
man PyCharm verwendet, weil die halt

00:45:02.010 --> 00:45:03.790
die beste Typ-Inferenz haben.

00:45:04.790 --> 00:45:05.990
Man merkt schon,

00:45:06.110 --> 00:45:06.990
dass das so der Java ist.

00:45:08.050 --> 00:45:10.630
Aber das können sie, also da sind sie richtig, richtig gut.

00:45:11.150 --> 00:45:14.170
Schon wieder Rust, für Rust haben sie auch einen eigenen geschrieben.

00:45:14.370 --> 00:45:16.110
Also die ganze Welt verwendet Rust Analyzer.

00:45:16.810 --> 00:45:23.630
Außer du nimmst Rust Rover von JetBrains, dann ist da ein eigener drinnen und sie haben auch Recht damit.

00:45:23.910 --> 00:45:28.830
Also das ist halt alles richtig gut integriert in die Werkzeuge, die sie zur Verfügung stellen.

00:45:30.070 --> 00:45:37.850
Ja, auch ein zusätzlicher Effekt, den das hat, dass halt quasi bei Python halt der statische Type Checker halt nicht so wirklich zur Sprache dazugehört.

00:45:38.050 --> 00:45:59.390
Ist halt auch, dass bei TypeScript ist es halt so, dass was sich sozusagen in der TypeScript-Sprache tut, auch immer sofort verfügbar ist. Und das ist bei Python nicht so, weil die statischen TypeChecker vor allen Dingen von den großen Wendeln gebaut werden, halt nicht MyPy, Dropbox, ich weiß nicht, ob die immer noch da so hauptsächlich dran sind, aber dann gibt es noch einen von Google, es gibt noch PyWrite.

00:46:00.770 --> 00:46:02.630
Die hängen sowieso immer so ein bisschen

00:46:02.630 --> 00:46:04.730
in den Versionen hinterher, weil

00:46:04.730 --> 00:46:06.750
sie ihre Code-Basis sowieso nicht

00:46:06.750 --> 00:46:08.610
an der aktuellsten Version halten können, weil sie das

00:46:08.610 --> 00:46:10.390
gar nicht schaffen, weil das einfach zu viel Arbeit ist.

00:46:11.030 --> 00:46:12.590
Das heißt, normalerweise

00:46:12.590 --> 00:46:14.430
bei MyPi hängst du halt immer so eine

00:46:14.430 --> 00:46:16.630
Version irgendwie von dem, was die Sprache eigentlich

00:46:16.630 --> 00:46:18.490
kann, zurück, was halt auch total

00:46:18.490 --> 00:46:19.310
doof ist einfach.

00:46:20.310 --> 00:46:22.350
Du musst ja auch noch darauf einigen, welches

00:46:22.350 --> 00:46:24.610
Subset des Typsystems du jetzt verwendest.

00:46:25.350 --> 00:46:25.470
Ja.

00:46:27.090 --> 00:46:27.290
Genau.

00:46:27.790 --> 00:46:29.350
Da kann ja gar nichts schief gehen.

00:46:30.770 --> 00:46:37.570
Ja, aber TypeScript-Versionen gibt es ja jetzt auch und ich habe auch schon Freude damit gehabt.

00:46:37.570 --> 00:46:40.570
Ja, also das TypeScript-Version-Management ist sehr stark in der Kritik, sehr keine Frage.

00:46:40.890 --> 00:46:43.950
Also das, jedes Release ist ein Breaking Change.

00:46:45.170 --> 00:46:47.790
Ja, und das ist aber einfach ein schwieriges Problem.

00:46:47.970 --> 00:46:52.190
Also ich glaube tatsächlich, dass TypeScript einfach dadurch, dass es eine jüngere Sprache ist,

00:46:53.090 --> 00:47:00.690
gewisse Fehler vermeiden konnte, die man halt vor 20 oder 25 oder 30 Jahren machen musste mit den ganzen alten Sprachen.

00:47:00.770 --> 00:47:03.290
aber manche Sachen sind halt

00:47:03.290 --> 00:47:05.290
immer noch nicht gelöst und Version Hell

00:47:05.290 --> 00:47:06.310
gehört halt dazu

00:47:06.310 --> 00:47:09.070
Wobei auch sagen wir, das TypeScript ist schon

00:47:09.070 --> 00:47:10.710
historisch gewachsen, also du merkst

00:47:10.710 --> 00:47:13.430
schon die dunklen Flecken

00:47:13.430 --> 00:47:15.430
der Vergangenheit und versuchst sie zu ignorieren

00:47:15.430 --> 00:47:17.550
das ist halt so, das passiert halt

00:47:17.550 --> 00:47:19.290
so wie Sachen verwendet werden

00:47:19.290 --> 00:47:21.190
hast du nachher die Probleme

00:47:21.190 --> 00:47:23.350
Ja und das muss sich ja auch

00:47:23.350 --> 00:47:25.150
an JavaScript orientieren, also es muss ja

00:47:25.150 --> 00:47:27.250
JavaScript kompatibel sein und da kriegst du halt

00:47:27.250 --> 00:47:28.730
viel, sag ich mal

00:47:28.730 --> 00:47:33.010
Ja, auch da kriegst du halt Historie, wenn ich es sehr freundlich ausdrücken will.

00:47:33.030 --> 00:47:35.650
Ein kleines bisschen Programmiersprachen-Historie mitgeliefert.

00:47:36.210 --> 00:47:44.090
Ja, ja, ja, ja, ja, aber ich wollte gerade nochmal auf Java ein, wo wir das gerade hatten.

00:47:44.130 --> 00:47:44.470
Schon alles gesagt.

00:47:44.470 --> 00:47:47.750
Das ist leider schon ein bisschen drüber, aber davon wieder weg.

00:47:47.750 --> 00:48:08.150
Aber da hatte ich nämlich auch noch so eine schöne, da habe ich letztens was sehr, sehr Schönes gelesen, dass halt einer der Autoren, auch von der Sprachspezifikation von Java, hat halt irgendwann mal so geschrieben zu den Generics, also dass sie die Generics eingeführt haben.

00:48:08.150 --> 00:48:33.910
Also ja, das war irgendwie ein Fehler. Und dann hat er irgendwie noch, in dem Buch selber findet man auch irgendwo so eine sehr schöne Fußnote, wo halt quasi die Annotation von Inam, Inam ist auch ein Partner ein Problem, aber in Java halt auch.

00:48:33.910 --> 00:48:47.970
Und Inam ist halt irgendwie definiert als, ich suche gerade, ob ich das hier finde, ah ja genau, ist eine generische Klasse definiert als Inam, Spitze, Klammer, T, Extens, Inam, Spitze, Klammer, T, Klammer, Zu, Klammer, Zu.

00:48:48.430 --> 00:48:54.230
Also diese rekursive Definition ist halt so ein bisschen schwierig zu verstehen.

00:48:54.470 --> 00:48:56.770
Wir haben inzwischen aufgegeben, es zu versuchen, Leuten zu erklären.

00:48:57.110 --> 00:48:58.510
Es gibt irgendwie Spezialisten,

00:48:59.390 --> 00:49:00.310
die uns versichert haben,

00:49:00.930 --> 00:49:02.890
über Typtheorie, die uns versichert haben,

00:49:02.970 --> 00:49:04.570
dass das schon alles okay ist und kein Problem

00:49:04.570 --> 00:49:06.130
und wir sollen uns einfach nicht so viel

00:49:06.130 --> 00:49:08.390
Gedanken drüber machen, was wir

00:49:08.390 --> 00:49:09.370
sehr gerne annehmen.

00:49:12.450 --> 00:49:14.770
Das Spannende ist ja bei den Java-Generics,

00:49:15.430 --> 00:49:15.910
dass die

00:49:15.910 --> 00:49:18.350
als einziges Element

00:49:18.350 --> 00:49:19.730
im Typsystem von Java

00:49:19.730 --> 00:49:22.890
keine Auswirkungen

00:49:22.890 --> 00:49:24.810
auf die Gestaltung der Laufzeit

00:49:24.810 --> 00:49:26.450
Objekte haben. Also das sind auch

00:49:26.450 --> 00:49:28.710
so, nach dem

00:49:28.710 --> 00:49:30.630
Compile-Schritt wird das einfach entfernt und

00:49:30.630 --> 00:49:31.890
nie wieder angesehen.

00:49:32.630 --> 00:49:34.430
Und das ist halt das Beeindruckende daran.

00:49:34.570 --> 00:49:36.730
Also das war halt auch so, oh shit, das brauchen

00:49:36.730 --> 00:49:38.750
wir jetzt, wir müssen das jetzt machen, im Release 1.5

00:49:38.750 --> 00:49:40.570
glaube ich war das, und das war

00:49:40.570 --> 00:49:42.890
die einfachste und unproblematischste

00:49:42.890 --> 00:49:44.010
Art, wie wir dazu kommen.

00:49:45.850 --> 00:49:46.250
Und

00:49:46.250 --> 00:49:48.710
alle Implikationen, die das hat, die werden bis heute

00:49:48.710 --> 00:49:50.910
mitgezogen. Du kannst quasi generische

00:49:50.910 --> 00:49:52.750
Klassen nie wirklich optimieren.

00:49:53.010 --> 00:49:54.790
Geht einfach nicht. Was halt spannend

00:49:54.790 --> 00:49:56.850
ist, weil die hast du halt überall, du hast überall

00:49:56.850 --> 00:49:57.530
Generics drin.

00:49:58.590 --> 00:50:00.490
Deswegen werden auch

00:50:00.490 --> 00:50:02.790
oft nur in der

00:50:02.790 --> 00:50:04.950
Standardbibliothek das generische

00:50:04.950 --> 00:50:06.750
Object verwendet, anstatt dass du einen generischen

00:50:06.750 --> 00:50:07.590
Typ-Parameter hast.

00:50:08.470 --> 00:50:10.510
Was ich mit Inam sein kann, weiß ich sowieso nicht.

00:50:10.690 --> 00:50:12.410
Also ich habe das gesehen bei unseren Kollegen

00:50:12.410 --> 00:50:14.770
und das ist kein Inam.

00:50:14.970 --> 00:50:15.810
Das ist kein Inam.

00:50:15.810 --> 00:50:18.810
Ich finde das eigentlich jetzt ein guter

00:50:18.810 --> 00:50:20.490
Zeitpunkt, um nochmal so ein bisschen zu erklären,

00:50:21.070 --> 00:50:22.670
worum es überhaupt geht und was da alles so drin ist.

00:50:22.670 --> 00:50:24.250
Wir sind jetzt auch schon auf so einem relativ hohen

00:50:24.250 --> 00:50:26.230
Frug-Level unterwegs, aber wir haben auch

00:50:26.230 --> 00:50:28.510
viele

00:50:28.510 --> 00:50:30.450
Menschen, die uns zuhören, die vielleicht noch gar nicht

00:50:30.450 --> 00:50:32.090
wissen, was denn ein Generic überhaupt ist

00:50:32.090 --> 00:50:34.310
und vielleicht sollten wir das einmal kurz

00:50:34.310 --> 00:50:35.930
ja

00:50:35.930 --> 00:50:38.330
wissen wollen, aber jetzt

00:50:38.330 --> 00:50:39.310
kriegen sie es halt mal gesagt.

00:50:41.430 --> 00:50:42.490
Im GFG-Nich gibt

00:50:42.490 --> 00:50:43.810
es auch Generics in Python.

00:50:43.810 --> 00:50:45.470
Ja, genau.

00:50:46.990 --> 00:50:48.150
Wovon

00:50:48.150 --> 00:50:48.470
geht an?

00:50:49.490 --> 00:50:50.670
Also das ist ja,

00:50:50.910 --> 00:50:53.710
diese Generics in den Typ-Annotationen,

00:50:53.750 --> 00:50:56.610
das ist ja wirklich nur sehr instruktiv,

00:50:56.750 --> 00:50:59.470
nur sehr so vage gesagt.

00:51:00.470 --> 00:51:03.490
Da ist die Erasure ja noch viel größer.

00:51:06.430 --> 00:51:09.050
Johannes, was ist denn bitte ein Generic?

00:51:10.570 --> 00:51:13.530
Ein Generic ist eine Spezialisierung eines Typen

00:51:13.530 --> 00:51:15.270
anhand eines anderen Typen.

00:51:15.390 --> 00:51:17.310
Und das klassische Beispiel ist da die Java-Liste.

00:51:18.230 --> 00:51:19.570
In Python hast du ja eine Liste,

00:51:20.030 --> 00:51:21.910
die, sag ich mal, dynamisch typisiert ist.

00:51:21.990 --> 00:51:22.870
Das heißt, wenn du eine Liste hast,

00:51:22.930 --> 00:51:24.730
kannst du da eine Zahl reintun und einen String und

00:51:24.730 --> 00:51:27.010
eine komplexe

00:51:27.010 --> 00:51:28.790
Zahl und ein Objekt und noch eine Liste.

00:51:29.570 --> 00:51:30.910
Das ist immer sehr unterhaltsam, wenn man das

00:51:30.910 --> 00:51:32.350
in den, wenn ich das in den

00:51:32.350 --> 00:51:34.650
Seminaren mache, wenn ich den Leuten Programmieren

00:51:34.650 --> 00:51:36.890
beibringe, die vielleicht schon mal eine Programmiersprache

00:51:36.890 --> 00:51:38.930
gesehen haben oder die schon was

00:51:38.930 --> 00:51:40.770
davon gehört haben und dann zeige ich hier so, jetzt kannst du da,

00:51:40.850 --> 00:51:42.810
du kannst noch eine Liste auch reintun oder ein Dictionary

00:51:42.810 --> 00:51:44.670
kannst du auch einfach in deine Liste reintun.

00:51:45.570 --> 00:51:46.870
Und in Java geht

00:51:46.870 --> 00:51:48.670
das nicht. In Java hat jede Liste

00:51:48.670 --> 00:51:50.350
einen Typen. Das heißt, du kannst,

00:51:51.530 --> 00:51:52.830
wenn du einfach nur List sagst, dann

00:51:52.830 --> 00:51:54.870
meinst du Liste von Object. Das heißt, alles, was

00:51:54.870 --> 00:51:56.930
du da reinschauen kannst, ist Object. Aber

00:51:56.930 --> 00:51:58.930
du kannst diese Liste

00:51:58.930 --> 00:52:00.790
spezieller gestalten, indem

00:52:00.790 --> 00:52:03.250
du eben diesen Generic-Mechanismus

00:52:03.250 --> 00:52:04.950
verwendest und sagst, du hast jetzt nicht eine Liste

00:52:04.950 --> 00:52:06.770
von Object, sondern du hast eine Liste von

00:52:06.770 --> 00:52:09.050
String. Das heißt, der Compiler

00:52:09.050 --> 00:52:10.670
weiß an bestimmten Stellen, dass

00:52:10.670 --> 00:52:12.790
dieser Typ, den du da hingeschrieben hast,

00:52:12.970 --> 00:52:14.510
der vorher vielleicht nur ein Platzhalter war,

00:52:15.890 --> 00:52:16.810
in TypeScript verwendet man

00:52:16.810 --> 00:52:18.750
dann oft T oder K oder V, das ist

00:52:18.750 --> 00:52:20.050
auch in Stefans Buch,

00:52:20.490 --> 00:52:21.770
kommt es mehrmals vor.

00:52:22.830 --> 00:52:41.330
Und dass du dann eben zu einem bestimmten Zeitpunkt diesen generischen Typen ersetzt durch einen konkreten Typen und sagst, okay, ich habe jetzt hier nicht eine Liste von Objects, sondern ich habe ganz klar eine Liste von String. Und dann kann der Compiler oder eben das Typsystem überprüfen, dass du da tatsächlich lauter Strings drin hast.

00:52:42.010 --> 00:53:09.230
Der Code, den du da ausführst, ist genau der gleiche, aber du hast jetzt eben einen spezifischen Typen für eine Liste von Strings gemacht. Und das hat gewisse Vorteile, zum Beispiel, wenn du da ein Objekt rausholst, kriegst du dann halt eben nicht nur ein generisches Object zurück, sondern du kriegst dann tatsächlich einen String zurück. Das ist der große Vorteil, den Java davon hat, dass du diese Accessor-Methoden hast, die dir die spezifischen Sachen rausgeben. War das korrekt erklärt, Stefan?

00:53:09.750 --> 00:53:10.390
Es ist cool.

00:53:10.470 --> 00:53:11.010
Als Experte.

00:53:12.890 --> 00:53:13.770
Gott, Experte.

00:53:14.030 --> 00:53:15.950
Ich bin nie ein Experte, ich bin einfach nur

00:53:15.950 --> 00:53:17.430
aufgehoben und schreibe den ganzen Mist auf.

00:53:18.370 --> 00:53:19.970
Ja gut, aber das macht dich zum Experte.

00:53:19.990 --> 00:53:21.630
Aber nein, das beschreibt es ziemlich gut.

00:53:21.750 --> 00:53:22.610
Du kannst mit

00:53:22.610 --> 00:53:26.070
Typparametern dir die Entscheidung

00:53:26.070 --> 00:53:27.770
auf den tatsächlichen

00:53:27.770 --> 00:53:29.330
Typen für später aufheben.

00:53:29.610 --> 00:53:30.670
Das ist das, was dort passiert.

00:53:31.430 --> 00:53:33.730
Und ebenso sagst du, dann wird das eine Arraylist

00:53:33.730 --> 00:53:35.810
von String oder eine Arraylist von

00:53:35.810 --> 00:53:37.830
Integer und du

00:53:37.830 --> 00:53:39.670
substituierst diesen Typparameter mit

00:53:39.670 --> 00:53:41.790
einem konkreten Typen und kriegst

00:53:41.790 --> 00:53:43.630
nachher auch solche

00:53:43.630 --> 00:53:45.190
konkreten Typen wieder retour.

00:53:45.790 --> 00:53:47.650
In manchem Programmiersprachen kannst du dann auch noch

00:53:47.650 --> 00:53:49.630
so Dinge wie Constraints

00:53:49.630 --> 00:53:51.690
oder Bounds angeben, wo du eben

00:53:51.690 --> 00:53:53.690
sagst, hey, du hast dort jetzt einen beliebigen

00:53:53.690 --> 00:53:55.690
Typparameter, ja, aber er muss

00:53:55.690 --> 00:53:57.530
einem gewissen Subtypen

00:53:57.530 --> 00:53:59.110
entsprechen. Das heißt, er muss eine gewisse

00:53:59.110 --> 00:54:01.470
Funktionalität zur Verfügung haben oder

00:54:01.470 --> 00:54:03.530
muss, also

00:54:03.530 --> 00:54:05.510
TypeScript ist ja

00:54:05.510 --> 00:54:07.650
strukturell typisiert,

00:54:08.190 --> 00:54:09.510
was bedeutet, dass du einfach

00:54:09.510 --> 00:54:11.450
sagst, hey, solange die Methoden dort sind und

00:54:11.450 --> 00:54:13.490
solange die Properties dort sind,

00:54:14.030 --> 00:54:15.510
passt schon, muss nicht den gleichen Namen

00:54:15.510 --> 00:54:17.230
haben, muss nicht in irgendeiner Hierarchie sein, sondern

00:54:17.230 --> 00:54:19.590
Hauptsache, schaut irgendwie so aus

00:54:19.590 --> 00:54:21.590
wie das eine, was ich da erwarten

00:54:21.590 --> 00:54:23.170
würde und dann haut das schon hin.

00:54:23.510 --> 00:54:25.430
Und dann kriegst du halt zum einen

00:54:25.430 --> 00:54:27.410
die Sicherheit, dass du nicht irgendwelche

00:54:27.410 --> 00:54:29.110
Typen reingibst, die nicht damit funktionieren

00:54:29.110 --> 00:54:30.290
würden.

00:54:31.930 --> 00:54:32.870
Und zum anderen

00:54:32.870 --> 00:54:35.610
kriegst du halt noch mehr Informationen über deinen

00:54:35.610 --> 00:54:37.110
Typ noch heraus, wenn du ihn dann vermeidest.

00:54:37.130 --> 00:54:39.170
Wie macht man das denn? Ein Python-Protokoll?

00:54:39.350 --> 00:54:43.670
Doch, in Python ist das seit 3.8. im Grunde auch so oder kann man das so machen.

00:54:43.750 --> 00:54:47.870
Man kann auch nominal typisiert das Ganze machen, aber da geht das jetzt auch.

00:54:47.870 --> 00:54:52.090
Genau, mit Typing-Protokolls geht das auch.

00:54:52.930 --> 00:54:53.990
Ja, genau.

00:54:54.470 --> 00:54:55.930
Habt ihr das schon mal irgendwo gesehen?

00:54:56.090 --> 00:54:57.050
Ja, ich verwende das.

00:54:57.890 --> 00:55:01.650
Also ich finde das eine großartige Idee, aber ich habe es noch nie irgendwo verwendet gesehen.

00:55:02.470 --> 00:55:11.890
Ja, ja, doch. Also ich kenne es auch vor allen Dingen aus dem Fluent Python Buch von Luciano Ramallo.

00:55:13.270 --> 00:55:29.650
Und der hat sich auch mit diesem Typisierungsthema stark beschäftigt und hat dann diverse Fehler in der TypeShed Repository, wo halt die ganzen, wo auch die Standardbibliothek von Python annotiert ist, hat er da gefunden.

00:55:30.270 --> 00:55:35.350
Und viele davon konnte er fixen mit diesem Structural Typing-Ansatz.

00:55:36.690 --> 00:55:41.090
Also Fehler im Sinne von halt die Annotationen waren halt irgendwie,

00:55:41.130 --> 00:55:44.110
da waren halt False Positives oder halt False Negatives möglich.

00:55:44.670 --> 00:55:47.030
Auch sehr interessant, wenn man sich halt anguckt,

00:55:47.390 --> 00:55:48.350
welche Fehler sind häufiger.

00:55:49.290 --> 00:55:53.050
False Positives sind viel, viel häufiger bei Typ-Annotationen

00:55:53.050 --> 00:55:53.770
als False Negatives.

00:55:53.770 --> 00:55:58.150
Also in der Python-Standard-Bibliothek waren es irgendwie achtmal so häufig.

00:55:58.150 --> 00:56:12.870
Was halt auch ein Hinweis darauf ist, dass es halt für Leute wichtiger ist, dass halt die, also falls positiv heißt, eine Annotation hat gesagt, nee, du kommst hier nicht rein, du bist nicht der richtige Typ, dein Typ ist hier nicht gefragt.

00:56:12.870 --> 00:56:17.430
sozusagen, obwohl es eigentlich doch

00:56:17.430 --> 00:56:19.570
okay gewesen wäre und

00:56:19.570 --> 00:56:20.790
also offenbar

00:56:20.790 --> 00:56:23.570
ist es halt irgendwie so

00:56:23.570 --> 00:56:25.510
mehr opportun, irgendwie auf der Seite von

00:56:25.510 --> 00:56:27.430
strikter zu sein, zu irren

00:56:27.430 --> 00:56:29.010
als umgekehrt.

00:56:30.130 --> 00:56:31.070
Was ja auch so ein bisschen

00:56:31.070 --> 00:56:33.470
vielleicht damit zusammenhängt, welche Leute

00:56:33.470 --> 00:56:35.270
das, für welche Leute das halt vor allen Dingen gut ist,

00:56:35.310 --> 00:56:37.430
nämlich die, die halt versuchen wollen, möglichst viel

00:56:37.430 --> 00:56:39.390
da draußen zu halten und wenn sie ein bisschen zu viel draußen

00:56:39.390 --> 00:56:41.390
halten, ist es besser, als was durchzulassen,

00:56:41.490 --> 00:56:43.470
was halt dann irgendwie knallt zur Laufzeit.

00:56:44.570 --> 00:56:45.470
Das wäre dann Full Snagged.

00:56:46.370 --> 00:56:48.210
Ja, genau.

00:56:48.950 --> 00:56:54.830
Und ja, der hat das lange erklärt in dem Buch

00:56:54.830 --> 00:56:56.210
und da habe ich das halt quasi her.

00:56:56.870 --> 00:56:58.450
Und ja, ich finde das eigentlich sehr nett,

00:56:58.550 --> 00:57:00.110
weil damit kann man im Grunde genau das Gleiche machen

00:57:00.110 --> 00:57:03.510
wie ein Typescript mit diesen Intersection- und Union-Types.

00:57:03.910 --> 00:57:07.270
Was ja auch irgendwie so, das ist halt so sehr cool eigentlich,

00:57:07.690 --> 00:57:08.270
dass das geht.

00:57:08.490 --> 00:57:15.510
Und das geht halt, wenn man jetzt so mit Abstract Base Classes das Ganze macht und nominal, geht das halt nicht so richtig.

00:57:18.090 --> 00:57:22.330
Das Problem ist, wenn du nominal arbeitest, du brauchst da auf dem Schlag eine Hierarchie auf.

00:57:22.470 --> 00:57:25.470
Auch wenn die implizit ist durch die Basistypen, die du definierst.

00:57:25.870 --> 00:57:37.090
Und das kannst du sehr schön und elegant umschiffen, indem du sagst, hey, alles, was ich erwarte, ist einfach nur, dass das Ding so ausschaut oder diese Werte und Eigenschaften hat, die ich an dieser Stelle erwarte.

00:57:38.230 --> 00:57:41.890
Methodennamen, Rückgabe-Werte, Property-Typen etc.

00:57:43.150 --> 00:57:46.490
Und ich sage mal, eine Programmiersprache wie JavaScript

00:57:46.490 --> 00:57:50.390
wäre gar nicht anders zu typisieren gewesen

00:57:50.390 --> 00:57:54.230
oder es wäre gar nicht möglich gewesen, die anders zu typisieren als mit einem strukturellen

00:57:54.230 --> 00:57:58.130
Typsystem, weil sonst praktisch kein Code mehr funktioniert hätte, den du irgendwie

00:57:58.130 --> 00:58:01.870
geschrieben hast. Und das war eben auch so ein Designprinzip von TypeScript, dass sie sagen,

00:58:01.870 --> 00:58:05.930
hey, wir wollen bestehenden JavaScript-Code unterstützen und mögliche Fehler

00:58:05.930 --> 00:58:07.750
herausfinden und nicht einfach nur

00:58:07.750 --> 00:58:09.470
aufgrund von einem

00:58:09.470 --> 00:58:11.730
APTR-geschaffenen

00:58:11.730 --> 00:58:13.690
Hierarchie-Konstrukt sagen, das passt

00:58:13.690 --> 00:58:14.270
oder passt nicht.

00:58:15.350 --> 00:58:17.690
Und ich glaube, es kann

00:58:17.690 --> 00:58:19.570
man gut vorstellen, dass das Python auch stark

00:58:19.570 --> 00:58:21.670
hilft. Ja, definitiv.

00:58:22.510 --> 00:58:23.770
Ja, das ist jetzt also seitdem

00:58:23.770 --> 00:58:25.810
also, ich meine, ist das auch in, glaube ich,

00:58:26.790 --> 00:58:27.690
in Go ist das

00:58:27.690 --> 00:58:29.510
ja auch so, mit den Interfaces in Go verhalten sich

00:58:29.510 --> 00:58:30.170
im Grunde auch so.

00:58:31.410 --> 00:58:33.530
Genau, du implementierst implizit

00:58:33.530 --> 00:58:35.250
Interfaces, wenn die Methodensignatur

00:58:35.250 --> 00:58:37.190
gleich ist, genau. Dann bist du

00:58:37.190 --> 00:58:38.090
kompatibel zum Interface.

00:58:39.350 --> 00:58:41.090
Ja, und

00:58:41.090 --> 00:58:43.130
also, ne, ich verwende das tatsächlich.

00:58:43.250 --> 00:58:45.110
Ich glaube auch, das ist halt, das ist eigentlich sozusagen das,

00:58:45.330 --> 00:58:46.910
wo es dann anfängt, Spaß zu machen.

00:58:47.090 --> 00:58:49.410
Weil, ehrlich gesagt, mit den Hierarchien,

00:58:49.570 --> 00:58:51.170
Klassenhierarchien und so, das ist nicht so

00:58:51.170 --> 00:58:52.850
meine Vorstellung von Spaß.

00:58:52.970 --> 00:58:54.890
Ja, also, ich glaube, das ist schon ein paar Mal

00:58:54.890 --> 00:58:55.630
gemeckert, ja.

00:58:58.630 --> 00:58:59.550
Ja, du hast ganz

00:58:59.550 --> 00:59:01.230
recht, Johannes. Das ist das, was, oder ich glaube,

00:59:01.270 --> 00:59:03.290
es war Johannes, oder was? Ja, genau, das ist das,

00:59:03.290 --> 00:59:05.150
was natürlich passiert. Du hast Klassen und dann hast

00:59:05.150 --> 00:59:07.030
der Hierarchien davon und dann benutzt du die und fertig.

00:59:07.610 --> 00:59:09.530
Das ist dem Konstrukt zu schulden.

00:59:10.150 --> 00:59:11.090
Und unter Kante ist

00:59:11.090 --> 00:59:13.290
Konstrukt auch nichts dafür. Das ist halt einfach so.

00:59:14.150 --> 00:59:15.370
Nee, und das liegt halt auch nahe.

00:59:15.490 --> 00:59:17.390
Du hast schon diese Hierarchie

00:59:17.390 --> 00:59:19.350
und dann benutzt du sie halt auch weiter. Du hast schon die Struktur.

00:59:19.550 --> 00:59:19.990
Also nehmen wir sie.

00:59:22.450 --> 00:59:23.310
Aber das

00:59:23.310 --> 00:59:25.190
ist dann eben das Problem, worauf du dann triffst.

00:59:25.550 --> 00:59:27.210
Du kommst an eine Stelle,

00:59:27.210 --> 00:59:29.170
wo du weißt, hier muss ich jetzt eigentlich

00:59:29.170 --> 00:59:31.130
nur addieren, aber der Typ, den du verlangen musst,

00:59:31.170 --> 00:59:33.250
ist halt irgendein ganz wilder

00:59:33.250 --> 00:59:34.990
oder ein ganz abgefahrener oder

00:59:34.990 --> 00:59:36.970
irgendeiner, der wo ganz anders in der Hierarchie drin ist.

00:59:37.110 --> 00:59:38.210
Und das, genau.

00:59:38.950 --> 00:59:40.730
Was mir sehr gut gefällt

00:59:40.730 --> 00:59:43.130
am Python-Typ-System, was ich gesehen

00:59:43.130 --> 00:59:44.890
habe, nur durchs drüberfliegen, ist

00:59:44.890 --> 00:59:46.990
dieses New-Type-Konstrukt, wo du

00:59:46.990 --> 00:59:48.790
sagen kannst, hey, es gibt schon einen bestehenden Typen

00:59:48.790 --> 00:59:50.770
und der ist vielleicht sehr, sehr

00:59:50.770 --> 00:59:52.930
freigebig, der ist vielleicht ein Integer-Dustring oder was auch immer,

00:59:53.190 --> 00:59:54.750
aber da kannst du ihm noch dieses eine Label

00:59:54.750 --> 00:59:56.950
verschaffen, damit du jetzt nicht irgendwelche unterschiedlichen

00:59:56.950 --> 00:59:58.770
Integer-Werte durcheinander kriegst oder

00:59:58.770 --> 01:00:00.690
irgendwelche Objektwerte, die ähnlich sind,

01:00:00.770 --> 01:00:02.450
durcheinander kriegst. Weil

01:00:02.450 --> 01:00:04.810
strukturelle Typ-Systeme funktionieren halt immer bis zu

01:00:04.810 --> 01:00:06.470
im Grad, was du sagen musst, hey, aber

01:00:06.470 --> 01:00:08.870
dieses eine Ding will ich da jetzt nicht herinnen haben,

01:00:08.950 --> 01:00:10.730
weil ich erwarte doch etwas anderes und kann

01:00:10.730 --> 01:00:12.470
das durch das Typsystem nicht so ausdrücken.

01:00:13.150 --> 01:00:14.790
Mach das Newtype, dann wird es explizit

01:00:14.790 --> 01:00:16.810
und dann kannst du genau sagen, hey, an dieser Stelle

01:00:16.810 --> 01:00:18.830
erwartest du etwas,

01:00:18.910 --> 01:00:20.830
was so ausschaut, aber es muss doch etwas anderes

01:00:20.830 --> 01:00:22.590
sein. Und das finde ich eigentlich ganz

01:00:22.590 --> 01:00:24.330
brauchbar.

01:00:25.170 --> 01:00:27.170
Genau, das benutze ich

01:00:27.170 --> 01:00:28.990
genau für diesen Use Case, dass man halt

01:00:28.990 --> 01:00:30.810
oft

01:00:30.810 --> 01:00:33.110
quasi sowas, zum Beispiel

01:00:33.110 --> 01:00:34.710
Integer möchte man einschränken,

01:00:34.810 --> 01:00:36.910
in der Range, aber das kann man im Typsystem nicht so richtig ausdrücken

01:00:36.910 --> 01:00:38.630
und ich finde, dann reicht oft schon,

01:00:38.810 --> 01:00:40.210
um den gleichen Effekt zu haben,

01:00:40.550 --> 01:00:42.850
im Newtype einzuführen, also wo ich das dann halt zum Beispiel

01:00:42.850 --> 01:00:44.890
aktuell brauche, ist halt, ich habe halt

01:00:44.890 --> 01:00:46.650
ein Jahr und ich weiß, dieses Jahr ist halt nur

01:00:46.650 --> 01:00:48.650
von 2025 bis 2040

01:00:48.650 --> 01:00:50.670
oder irgendwie sowas und

01:00:50.670 --> 01:00:52.650
mir reicht

01:00:52.650 --> 01:00:54.670
im Grunde, wenn, ich

01:00:54.670 --> 01:00:56.970
mache das gar nicht über das Typsystem,

01:00:57.070 --> 01:00:58.730
dass diese Range dann sozusagen abgesichert

01:00:58.730 --> 01:01:00.650
wird, aber allein dadurch,

01:01:00.650 --> 01:01:02.650
dass ich sage, ich definiere den Newtype

01:01:03.290 --> 01:01:04.650
hier, der halt eigentlich

01:01:04.650 --> 01:01:06.610
ein Int ist, kann mir der Type-Checker

01:01:06.610 --> 01:01:08.210
sagen, wenn ich

01:01:08.210 --> 01:01:10.530
irgendwie mal ein anderes Int da reingesteckt habe, was ich

01:01:10.530 --> 01:01:12.750
nicht mal als Ja irgendwo anders deklariert habe

01:01:12.750 --> 01:01:14.490
und krieg dann sozusagen

01:01:14.490 --> 01:01:16.470
den Effekt, dass wenn da irgendjemand irgendwas reinsteckt,

01:01:16.530 --> 01:01:18.550
was kein Ja ist, dann gibt's halt auch

01:01:18.550 --> 01:01:20.270
ein, sagt der Type-Checker halt schon,

01:01:20.730 --> 01:01:22.490
okay, nee, das sieht nicht gut aus.

01:01:23.070 --> 01:01:24.430
Und so kann man sich halt das

01:01:24.430 --> 01:01:25.250
sozusagen so ein bisschen

01:01:25.250 --> 01:01:28.430
herbeiemulieren, dass man

01:01:28.430 --> 01:01:30.650
irgendwie damit auch überprüft, ob das

01:01:30.650 --> 01:01:32.130
inhaltlich Sinn macht.

01:01:33.630 --> 01:01:35.470
Aber noch cooler wäre es natürlich, wenn du auch

01:01:35.470 --> 01:01:36.910
die Werte angeben könntest.

01:01:37.710 --> 01:01:38.530
Entschuldigung, Stefan.

01:01:39.530 --> 01:01:39.790
Weißt du?

01:01:42.390 --> 01:01:43.410
Also gerade mit dem,

01:01:43.910 --> 01:01:45.550
also in TypeScript kannst du

01:01:45.550 --> 01:01:47.350
das ein bisschen, du kannst teilweise

01:01:47.350 --> 01:01:49.170
Werte oder

01:01:49.170 --> 01:01:51.270
geringere Wertbereiche definieren.

01:01:51.490 --> 01:01:52.850
Also in TypeScript ist es das Spannende,

01:01:53.550 --> 01:01:55.310
wie in jedem Typsystem, du hast

01:01:55.310 --> 01:01:57.510
Wertemengen und

01:01:57.510 --> 01:01:59.390
du definierst ja nur, ob dieser eine Wert,

01:01:59.430 --> 01:02:01.510
den du hast, jetzt in diese Menge passt

01:02:01.510 --> 01:02:03.450
oder nicht. Das sind sehr

01:02:03.450 --> 01:02:05.150
große Mengen zum Teil, String, Number

01:02:05.150 --> 01:02:07.490
oder alle Objects.

01:02:07.830 --> 01:02:09.250
Zum Teil sind sie halt auf deine

01:02:09.250 --> 01:02:11.370
Objekttypen heruntergebrochen,

01:02:11.490 --> 01:02:13.290
wo du sagst, diese Kombination an

01:02:13.290 --> 01:02:15.630
Properties, die gewisse Typen haben,

01:02:16.090 --> 01:02:17.170
erlaubst du dort oder nicht.

01:02:17.950 --> 01:02:18.930
Du kannst aber auch sagen, hey,

01:02:19.170 --> 01:02:20.790
dieser einzige

01:02:20.790 --> 01:02:23.350
oder einzelne konkrete Wert,

01:02:24.230 --> 01:02:24.930
die Zahl 1

01:02:24.930 --> 01:02:26.650
des String-Stefan, was auch immer,

01:02:27.270 --> 01:02:29.670
kann auch als Typ gelten.

01:02:29.670 --> 01:02:31.590
Das heißt, du kannst einen Wert haben, wo du

01:02:31.590 --> 01:02:36.410
Du sagst, alles, was diese Variable annehmen darf, ist der Wert 1.

01:02:37.870 --> 01:02:42.250
Und das klingt am Anfang doof, weil was machst du mit einer Variable, die nur 1 sein kann?

01:02:42.470 --> 01:02:43.310
Du kannst es schenken.

01:02:44.070 --> 01:02:49.810
Aber du kannst noch diese Literal-Types oder Value-Types, wie es du benannt hast, Johannes,

01:02:50.570 --> 01:02:51.970
kombinieren mit anderen Value-Types.

01:02:51.970 --> 01:02:58.010
Und kannst dann zum Beispiel alle validen Augenzahlen eines Würfels darstellen.

01:02:58.190 --> 01:03:00.410
1 oder 2 oder 3 oder 4 oder 5 oder 6.

01:03:00.930 --> 01:03:05.690
Also damit hast du schon einen sehr engen Wertebereich definiert

01:03:05.690 --> 01:03:10.070
und weißt noch aus, wenn ein Wert da reinkommt,

01:03:10.230 --> 01:03:14.010
dann hat er garantiert eine dieser sechs Zahlen.

01:03:15.950 --> 01:03:18.650
Und das ist spannend, das kannst du auch mit Strings machen.

01:03:19.130 --> 01:03:20.710
Und was halt dann wirklich elegant ist, ist,

01:03:20.810 --> 01:03:23.530
dass du zum Beispiel Strings mit gewissen Pattern definieren kannst.

01:03:23.530 --> 01:03:27.950
Du kannst sagen, hey, du erlaubst alle Strings, die mit on anfangen,

01:03:28.050 --> 01:03:29.530
weil du gerade dein Eventsystem implementierst

01:03:30.210 --> 01:03:34.950
und du hast halt On-Click, On-Key-Down, On-Key-Press, was auch immer.

01:03:35.390 --> 01:03:40.070
Das heißt, es muss mit On anfangen und nachher muss der erste Buchstabe unbedingt ein Großbuchstabe sein.

01:03:40.550 --> 01:03:42.870
Solches Tricks akzeptierst du, andere akzeptierst du nicht.

01:03:42.870 --> 01:03:51.150
Da kannst du wirklich sehr elegant Wertebereiche definieren, mit denen du korrekte Werte angibst,

01:03:51.430 --> 01:03:55.810
mit denen du auch über deine Werte diverse Aussagen treffen kannst, die dir nachher helfen,

01:03:56.490 --> 01:04:00.010
die aber jetzt nicht so übermäßig komplex sind.

01:04:00.170 --> 01:04:06.830
Dass du jetzt sagst, hey, das ist jetzt viel zu viel Aufwand, das zu definieren.

01:04:07.670 --> 01:04:12.030
Mein Lieblingsbeispiel ist immer noch HTTP-Methoden,

01:04:12.630 --> 01:04:14.830
Get, Post, Delete, was auch immer.

01:04:15.390 --> 01:04:21.430
Oder HTTP-Error-Codes, da gibt es 70 um den Dreh.

01:04:22.370 --> 01:04:27.510
Ich weiß jetzt nicht, ob es 201 gibt, ob es 217 noch gibt, weiß ich nicht.

01:04:28.190 --> 01:04:30.150
Das kann mir dieser Union-Typ sehr, sehr schön sagen.

01:04:30.170 --> 01:04:31.970
hat. Und dann bin ich mir

01:04:31.970 --> 01:04:33.710
sicher, dass ich den richtigen

01:04:33.710 --> 01:04:35.770
HTTP-Statuscode in meiner

01:04:35.770 --> 01:04:37.690
Response schicke und

01:04:37.690 --> 01:04:39.170
brauche nicht großartig überlegen,

01:04:39.910 --> 01:04:41.850
ob ich noch im richtigen Wertebereich bin oder nicht.

01:04:42.650 --> 01:04:43.870
Ich muss mich

01:04:43.870 --> 01:04:45.450
einmal korrigieren. Ich habe eben nachgelesen,

01:04:45.510 --> 01:04:47.010
Value-Types ist nicht das richtige Wort.

01:04:47.890 --> 01:04:49.910
Das bezieht sich auch auf etwas anderes.

01:04:50.530 --> 01:04:51.470
Das wird als

01:04:51.470 --> 01:04:53.810
Abgrenzung zum Reference-Type verwendet.

01:04:54.510 --> 01:04:55.750
Also ob man einen Wert oder

01:04:55.750 --> 01:04:57.850
eine Referenz hat. Aber das Konzept

01:04:57.850 --> 01:04:59.910
ist

01:04:59.910 --> 01:05:01.830
hast du gerade sehr schön erklärt. Vielen Dank, Steffen.

01:05:02.450 --> 01:05:03.690
Das ist auch in Kapitel

01:05:03.690 --> 01:05:05.690
4 beschrieben von meinem Buch

01:05:05.690 --> 01:05:06.490
und da bist du ja noch nicht.

01:05:07.510 --> 01:05:09.710
Das haben wir vorhin schon festgestellt, ich habe noch nicht

01:05:09.710 --> 01:05:11.870
weit genug gelesen. Aber ich

01:05:11.870 --> 01:05:13.270
habe es jetzt wieder rausgeholt und jetzt

01:05:13.270 --> 01:05:15.810
lege ich es mir unter das Kopfkissen

01:05:15.810 --> 01:05:17.550
und werde das per Diffusion

01:05:17.550 --> 01:05:19.690
aufnehmen. So wird die

01:05:19.690 --> 01:05:21.710
Matura geschafft mit dem

01:05:21.710 --> 01:05:23.050
Mathematikbuch unter dem Kopfkissen.

01:05:23.910 --> 01:05:24.310
Funktioniert.

01:05:25.730 --> 01:05:27.530
Ich finde, wir müssen noch ein bisschen darüber reden,

01:05:27.530 --> 01:05:29.130
wie man das so in Python

01:05:29.130 --> 01:05:30.830
dann machen kann noch und wie man das

01:05:30.830 --> 01:05:33.130
Typing-Modul vielleicht noch so ein bisschen benutzt.

01:05:33.850 --> 01:05:35.030
Wir hatten jetzt ein Newtype, was

01:05:35.030 --> 01:05:36.830
irgendwie ganz cool ist. Wir hatten die Generics.

01:05:37.530 --> 01:05:39.210
Ja, also Generics, achso, genau.

01:05:39.350 --> 01:05:40.930
Wo wir dann schon mal, da habe ich nämlich jetzt heute

01:05:40.930 --> 01:05:45.010
eins gehabt, da dachte ich mir so,

01:05:45.090 --> 01:05:47.030
oh mein Gott, wenn, hoffentlich fragt das keiner, deswegen frage ich

01:05:47.030 --> 01:05:49.070
das jetzt mal, kann mir

01:05:49.070 --> 01:05:51.070
einer vielleicht erklären, was der Unterschied zwischen

01:05:51.070 --> 01:05:53.150
Co-Variant, Contra-Variant und In-Variant und so

01:05:53.150 --> 01:05:55.110
ist, weil das kann man nämlich auch mit angeben

01:05:55.110 --> 01:05:57.090
und ich dachte mir so, okay, ich kann es ja angeben, aber

01:05:57.090 --> 01:05:58.550
oh Gott, was bedeutet das eigentlich?

01:05:58.610 --> 01:05:59.950
Und was macht dann Bound und so?

01:06:00.150 --> 01:06:00.310
Ja.

01:06:02.290 --> 01:06:04.210
Ich kann es aus einer Typtheorie sagen, was Co- und

01:06:04.210 --> 01:06:06.170
Contra-Variant ist. Ich weiß aber nicht, ob das so

01:06:06.170 --> 01:06:07.970
auf Python auch zutrifft.

01:06:08.970 --> 01:06:10.470
Aber ich versuche

01:06:10.470 --> 01:06:11.290
es jetzt mal so zu erklären.

01:06:12.130 --> 01:06:13.430
Co-Variant ist, wenn du

01:06:13.430 --> 01:06:16.490
Schnell die

01:06:16.490 --> 01:06:16.990
Petitfragen.

01:06:18.190 --> 01:06:20.070
Nein, es ist irrsinnig schwierig zu erklären.

01:06:20.350 --> 01:06:22.090
Lass mich kurz mein zweites Buch aufmachen, weil da wird

01:06:22.090 --> 01:06:22.470
Zeichnung.

01:06:25.710 --> 01:06:28.430
Also bevor ich jetzt allgemeine

01:06:28.430 --> 01:06:29.990
Beschreibungen erkläre, sage ich es lieber mal so.

01:06:30.470 --> 01:06:32.490
In einer Co-Varianten-Beziehung

01:06:32.490 --> 01:06:34.430
hast du zum Beispiel einen Typ, der

01:06:34.430 --> 01:06:36.330
ist String oder Number,

01:06:37.030 --> 01:06:38.610
was bedeutet, dass wenn du einen Wert

01:06:38.610 --> 01:06:40.570
hast, der Number ist, dann kannst du

01:06:40.570 --> 01:06:42.630
dir auf jeden Fall auf diesen einen Typen

01:06:42.630 --> 01:06:44.290
zuweisen, der String oder Number sein kann.

01:06:44.650 --> 01:06:46.790
Das heißt, je enger dieser Wertebereich

01:06:46.790 --> 01:06:47.790
wird,

01:06:49.130 --> 01:06:50.510
hat kein Effekt drauf,

01:06:50.570 --> 01:06:52.650
kannst du weiterhin darauf zuweisen.

01:06:53.330 --> 01:06:54.770
Die Contra-Variante ist genau umgekehrt.

01:06:54.830 --> 01:06:56.010
Du kannst zum Beispiel jetzt nicht

01:06:56.010 --> 01:06:58.930
eine Funktion, die als ersten Parameter

01:06:58.930 --> 01:07:00.690
String oder Number, oder

01:07:00.690 --> 01:07:02.830
einen Funktionstypen, der

01:07:02.830 --> 01:07:05.030
als ersten Parameter String oder Number erwartet,

01:07:05.170 --> 01:07:05.890
kannst du jetzt nicht

01:07:05.890 --> 01:07:08.810
eine echte Funktion zuweisen, die

01:07:08.810 --> 01:07:10.530
nur String erwartet, weil ja

01:07:10.530 --> 01:07:13.090
der Fall, dass auch ein Number als Parameter

01:07:13.090 --> 01:07:14.770
sein kann, nicht dadurch abgedeckt wird.

01:07:15.090 --> 01:07:17.090
Das heißt, du hast der Typ zwar auch ein Subtyp,

01:07:17.170 --> 01:07:18.730
der Parametertyp ist ein Subtyp

01:07:18.730 --> 01:07:19.230
vom anderen,

01:07:20.210 --> 01:07:23.050
aber nachdem der in einer Funktion steht,

01:07:23.250 --> 01:07:24.810
sind die nicht zueinander kompatibel, sondern

01:07:24.810 --> 01:07:26.670
nur umgekehrt. Das heißt, du kannst eine Funktion,

01:07:26.990 --> 01:07:28.690
einen Funktionstypen definieren, der als ersten

01:07:28.690 --> 01:07:30.930
Parameter eine Number angibt, was bedeutet,

01:07:31.070 --> 01:07:32.790
dass du auch Funktionen zuweisen kannst,

01:07:32.910 --> 01:07:33.770
die String oder Number

01:07:33.770 --> 01:07:36.650
erwarten, weil eben dieser eine Fall

01:07:36.650 --> 01:07:38.350
abgedeckt ist. Und das ist der Unterschied zwischen

01:07:38.350 --> 01:07:40.630
Kovarianz und Kontravarianz. Brauchst du eigentlich nie,

01:07:40.690 --> 01:07:42.470
macht halt irgendwelche komischen Fehlermeldungen, wenn du

01:07:42.470 --> 01:07:44.630
irgendwelche Sachen zuweisen willst, die dann nicht so funktionieren.

01:07:46.350 --> 01:07:46.670
Ist

01:07:46.670 --> 01:07:48.250
aber, glaube ich, in der Typtheorie

01:07:48.250 --> 01:07:50.090
die korrekte Beschreibung.

01:07:51.070 --> 01:07:52.450
Ist nicht kompliziert, ich möchte euch da für die

01:07:52.450 --> 01:07:54.450
Shownotes eine Grafik zur Verfügung stellen,

01:07:54.450 --> 01:07:55.870
die das wunderschön erklärt.

01:07:56.830 --> 01:07:58.350
Und da suche ich mir den Link jetzt wirklich

01:07:58.350 --> 01:07:59.990
raus aus meinem Buch, weil das habe ich genau

01:07:59.990 --> 01:08:02.010
aus dem Grund habe ich es da reingetan.

01:08:02.210 --> 01:08:03.750
Weil das sind die Sachen, die merke ich mir selber nie genau.

01:08:04.690 --> 01:08:06.270
Das ist was man immer nachlesen muss. Also in welche

01:08:06.270 --> 01:08:08.250
Richtung kann man was irgendwie doch voneinander

01:08:08.250 --> 01:08:09.690
erben, wenn ich das richtig verstehe?

01:08:11.150 --> 01:08:11.510
Generisieren.

01:08:12.770 --> 01:08:14.270
Generisieren. Also ich habe es

01:08:14.270 --> 01:08:16.310
jetzt hier auch gerade, wenn jemand

01:08:16.310 --> 01:08:17.370
anders spricht, kann ich ja googeln.

01:08:19.630 --> 01:08:20.350
Also so wie ich

01:08:20.350 --> 01:08:22.070
das jetzt hier verstehe, ist es, das

01:08:22.070 --> 01:08:23.950
bezieht sich direkt auf Python hier

01:08:23.950 --> 01:08:27.710
und die Qualitätsquelle Stack Overflow

01:08:27.710 --> 01:08:28.350
kann man ja auch verlinken.

01:08:30.650 --> 01:08:31.670
Es wird hier so erklärt,

01:08:31.730 --> 01:08:32.490
du hast zwei Klassen,

01:08:32.730 --> 01:08:34.670
Basisklasse und eine abgeleitete Klasse.

01:08:34.830 --> 01:08:35.270
Die derived.

01:08:36.630 --> 01:08:36.950
Genau.

01:08:37.690 --> 01:08:38.270
B und D,

01:08:38.610 --> 01:08:40.270
also Basisklasse und abgeleitete Klasse.

01:08:40.390 --> 01:08:42.150
Und du hast irgendeine generische Typenliste

01:08:42.150 --> 01:08:43.610
mit irgendeinem Typen drin.

01:08:44.290 --> 01:08:45.250
Und jetzt ist die Frage,

01:08:45.370 --> 01:08:46.570
wenn du eine Liste hast,

01:08:46.870 --> 01:08:48.790
die den Typen B hat,

01:08:48.870 --> 01:08:49.810
also den Basistypen,

01:08:50.250 --> 01:08:51.530
kannst du die dann da verwenden,

01:08:51.970 --> 01:08:58.050
wo du eine Liste vom Typen D erwartest, also eine abgeleitete Klasse.

01:08:58.970 --> 01:08:59.910
Oder ist es andersrum?

01:09:00.790 --> 01:09:02.550
Das wäre dann Co-Variant oder Kontra-Variant.

01:09:03.130 --> 01:09:05.430
Genau, das eine ist Co-Variant und das andere ist Kontra-Variant,

01:09:05.530 --> 01:09:08.830
weil du eben sagst, okay, wenn du den als Generic verwendest,

01:09:09.390 --> 01:09:10.850
dann geht die Beziehung in die eine Richtung

01:09:10.850 --> 01:09:12.530
oder die Beziehung geht in die andere Richtung.

01:09:13.490 --> 01:09:16.030
Und das ist natürlich schön, dass man da zwei Worte genommen hat,

01:09:16.070 --> 01:09:17.250
die exakt gleich klingen.

01:09:17.250 --> 01:09:21.250
Also Co-Variant ist, wenn man quasi annotiert mit der Implementierung

01:09:21.770 --> 01:09:23.870
und Contra-Variant ist, wenn man mit der

01:09:23.870 --> 01:09:25.730
Basis

01:09:25.730 --> 01:09:27.630
notiert, ja. Und

01:09:27.630 --> 01:09:29.610
Invariant wäre dann, wenn man nicht

01:09:29.610 --> 01:09:30.950
beides verwenden darf, weil

01:09:30.950 --> 01:09:33.930
der sagt ja halt, nö, das ist nicht genau

01:09:33.930 --> 01:09:34.570
das, was ich erwarte.

01:09:35.710 --> 01:09:37.870
Ja, irgendwie so. Für genauere Sachen

01:09:37.870 --> 01:09:39.850
muss man PEP484 lesen, das haben wir

01:09:39.850 --> 01:09:40.810
ja sicherlich alle schon gemacht.

01:09:44.450 --> 01:09:46.050
Muss man gar nicht genauer drauf eingehen.

01:09:47.050 --> 01:09:47.990
Ich packe die Grafik

01:09:47.990 --> 01:09:49.270
in die Show Notes und dann schauen wir mal.

01:09:50.070 --> 01:09:50.170
Genau.

01:09:51.770 --> 01:09:57.090
Ja, aber genau, ich dachte

01:09:57.090 --> 01:09:59.290
auch so, also man kann das ja angeben

01:09:59.290 --> 01:10:00.970
und dann dachte ich so, ich hab das noch nie verwendet, ist das

01:10:00.970 --> 01:10:03.090
irgendwie, hab ich was, pass ich

01:10:03.090 --> 01:10:04.950
was oder? Und was macht dann Bound?

01:10:06.590 --> 01:10:06.990
Also weil das

01:10:06.990 --> 01:10:09.150
macht man ja irgendwie auch bei den Contra-Variants

01:10:09.150 --> 01:10:10.210
oder ist das schon das?

01:10:10.210 --> 01:10:10.750
I don't know.

01:10:11.730 --> 01:10:13.970
Steht zumindest in der Types, Pricing, Typing.

01:10:14.690 --> 01:10:15.770
Tatsächlich ist in dem

01:10:15.770 --> 01:10:17.910
PEP484 eine sehr schöne Erklärung drin.

01:10:19.350 --> 01:10:19.830
Mit

01:10:19.830 --> 01:10:21.090
Employees und Managers.

01:10:21.770 --> 01:10:29.630
Wenn du eine Liste, wenn du eine Funktion hast, die eine Liste von Employee nimmst, solltest du da, kannst du da eine Liste von Managers reingeben?

01:10:30.850 --> 01:10:40.210
Und für manche Funktionen kann das ja sein, wenn du halt sagst, okay, wir müssen Gehalt auszahlen, das müssen Angestellte kriegen und wenn die Angestellten Manager sind, dann ist es halt so.

01:10:41.490 --> 01:10:49.690
Kann aber auch nein sein, dass du zum Beispiel, keine Ahnung, alle die Angestellten aufsetzt.

01:10:49.690 --> 01:10:51.430
Alle Angestellten feuern, nur Manager feuern.

01:10:51.770 --> 01:11:07.910
Genau. Aber dass du zum Beispiel jemanden hinzufügst zu dieser Liste. Und wenn du sagst, okay, die Funktion nimmt eine Liste, die die Angestellte enthält, dann kannst du in diese Liste auch einen Angestellten reintun. Wenn du aber eine Liste von Managern reingegeben hast, dann geht das nicht.

01:11:09.290 --> 01:11:25.090
Und das ist jetzt eben genau so eine Frage, wo du beide Optionen haben kannst, also so eine Situation, wo du beide haben kannst und das tatsächlich auch eigentlich beantworten können musst, ob du da eine abgeleitete oder eine Basisklasse reingeben darfst.

01:11:25.090 --> 01:11:26.670
Das ist eine Co-Variante, eine Contra-Variante.

01:11:26.790 --> 01:11:28.970
Und der Bound ist dann quasi tatsächlich die,

01:11:29.530 --> 01:11:31.250
wenn dann erst die Manager gefallen,

01:11:31.390 --> 01:11:33.610
weil das die spezialisiertere Variante ist.

01:11:35.730 --> 01:11:38.090
Ja, wir haben noch mehr von dem Typing-Modul,

01:11:38.210 --> 01:11:40.530
damit wir uns noch mehr schöne Sachen dazu erzählen können

01:11:40.530 --> 01:11:43.290
und mehr ergänzen können mit präzisem Fachwissen.

01:11:43.390 --> 01:11:45.950
Und zwar den Type-Adias und die Type-Ware,

01:11:46.410 --> 01:11:47.610
die da noch irgendwie dazu können.

01:11:47.730 --> 01:11:48.530
Also was ist denn der Unterschied?

01:11:48.530 --> 01:11:50.690
Und man kann ja auch noch das schöne Keyword Type

01:11:50.690 --> 01:11:52.430
dazu schreiben und sowas.

01:11:53.290 --> 01:11:55.330
Ich meine, bei Type-Alias, das

01:11:55.330 --> 01:11:57.590
kannst du auch einfach so hinschreiben, es ist nur eine explizitere

01:11:57.590 --> 01:11:59.330
Darstellung und manchmal ist es halt

01:11:59.330 --> 01:12:01.270
problematisch, wenn du zum Beispiel einfach einen String verwendest,

01:12:01.310 --> 01:12:03.290
den du ja auch quasi benutzen kannst,

01:12:03.430 --> 01:12:05.090
statt, und manchmal muss man das ja auch

01:12:05.090 --> 01:12:06.950
um zyklische Imports zu vermeiden und so,

01:12:07.590 --> 01:12:09.390
dann ist halt unklar, was gemeint ist,

01:12:09.410 --> 01:12:10.770
wenn man den nicht Type-Alias davor schreibt.

01:12:10.770 --> 01:12:12.590
Also beispielsweise, wenn ich jetzt irgendwie eine Union habe,

01:12:12.670 --> 01:12:14.650
das kann jetzt mehrere Sachen sein, dann kann ich dann

01:12:14.650 --> 01:12:16.670
Type-Alias dafür verwenden, dass das damit

01:12:16.670 --> 01:12:18.530
gemeint ist, dass es einen Namen gibt. Ja, aber du könntest ja auch einfach

01:12:18.530 --> 01:12:20.510
hinschreiben, myUnion gleich

01:12:20.510 --> 01:12:22.150
und dann irgendwie

01:12:22.150 --> 01:12:24.390
der Typ, Pipe-Symbol,

01:12:24.550 --> 01:12:24.870
der andere.

01:12:26.210 --> 01:12:27.730
Das ist dann ein Type-Alias schon.

01:12:28.090 --> 01:12:30.270
Das selber kann ich annotieren mit, nein, ist es nicht?

01:12:30.730 --> 01:12:31.850
Ja, also du könntest damit dann wieder

01:12:31.850 --> 01:12:34.030
annotieren, aber wenn du

01:12:34.030 --> 01:12:35.650
jetzt zum Beispiel da Strings verwenden

01:12:35.650 --> 01:12:38.050
wollen würdest für die Typ-Typen,

01:12:38.150 --> 01:12:40.130
dann geht's

01:12:40.130 --> 01:12:40.770
halt nicht mehr so richtig.

01:12:42.310 --> 01:12:43.890
Also Type-Alias macht das dann halt

01:12:43.890 --> 01:12:45.410
explizit, dass das halt sozusagen...

01:12:45.410 --> 01:12:48.370
Und die Type-Ware,

01:12:48.370 --> 01:12:50.370
das hatten wir eben, TVK, TKV,

01:12:50.530 --> 01:12:51.890
warum TKV jetzt da

01:12:51.890 --> 01:12:53.830
im besonderen Sinne, weil ich diese kurzen Dinge

01:12:53.830 --> 01:12:55.710
nicht, also einer der Gründe, warum ich Go nicht leiden kann,

01:12:55.770 --> 01:12:56.550
sind diese

01:12:56.550 --> 01:12:59.650
Ein-Charakter-Variablen-Namen, aber

01:12:59.650 --> 01:13:01.770
ja. Ja, das sind halt die Generics, oder, die wir

01:13:01.770 --> 01:13:03.650
vorhin hatten. Ja, genau. Stefan, du hast angesetzt.

01:13:04.050 --> 01:13:04.790
Erklär uns, was Type war.

01:13:05.050 --> 01:13:07.470
Ja, also ich habe jetzt ganz kurz diesen PEP-Vier-Ocht-Vier

01:13:07.470 --> 01:13:09.330
aufgemacht und der ist wunderschön.

01:13:11.050 --> 01:13:11.830
Der ist super, oder?

01:13:11.830 --> 01:13:13.910
Also eine Type-Variable, also ich sage immer

01:13:13.910 --> 01:13:15.790
Type-Parameter dazu, aber das ist im Grunde

01:13:15.790 --> 01:13:17.130
genau das Gleiche. Das ist eben diese

01:13:17.130 --> 01:13:19.570
ein Typ, der später durch

01:13:19.570 --> 01:13:21.590
einen konkreten Typ ersetzt wird. Das heißt, du kannst

01:13:21.590 --> 01:13:23.390
Also jetzt sagen wir, du hast diese Typvariable

01:13:23.390 --> 01:13:25.550
in diesem Beispiel von pep484, das ist st,

01:13:26.490 --> 01:13:28.630
seist type wird das heißen dort,

01:13:28.730 --> 01:13:29.830
weil da geht es um seist,

01:13:31.510 --> 01:13:33.210
wo du sagst, hey, du machst jetzt eine Funktion,

01:13:33.730 --> 01:13:37.210
die erlaubt x beliebige Typen,

01:13:38.070 --> 01:13:41.690
allerdings kannst du sie durch irgendeinen Bound,

01:13:41.690 --> 01:13:42.750
das ist das zweite dort,

01:13:43.630 --> 01:13:46.630
der zweite Parameter, einschränken.

01:13:46.930 --> 01:13:48.150
Also ein Bound sagt hier,

01:13:49.530 --> 01:13:52.030
oder der generelle Typ-Rameter sagt dir,

01:13:52.570 --> 01:13:55.690
alle möglichen Werte, aber später nur ein konkreter.

01:13:56.510 --> 01:13:58.990
Und der Bound sagt dir, alle möglichen Werte,

01:13:59.270 --> 01:14:02.550
die auch diese Eigenschaften erfüllen, später ein konkreter.

01:14:02.990 --> 01:14:04.690
Und das ist dort in diesem Beispiel recht gut,

01:14:04.770 --> 01:14:06.890
weil da wird Seist als Bound definiert,

01:14:06.890 --> 01:14:13.950
was bedeutet, dass du eine Länge definieren können musst

01:14:13.950 --> 01:14:16.090
oder eine Länge lesen können musst.

01:14:17.150 --> 01:14:19.990
In Python hast du ja nur diese Hilfsfunktion,

01:14:20.110 --> 01:14:22.070
du hast ja selten Methoden auf Klassen,

01:14:22.170 --> 01:14:23.130
soweit ich das weiß.

01:14:24.750 --> 01:14:28.130
Deswegen brauchst du halt überall diese Bounds.

01:14:28.510 --> 01:14:29.570
Andererseits könntest du ja sagen,

01:14:29.650 --> 01:14:31.690
du hast irgendeine Subklasse oder so.

01:14:32.430 --> 01:14:34.430
Aber Bound ist auch etwas,

01:14:34.790 --> 01:14:36.410
das kennen wir in anderen Programmiersprachen auch.

01:14:37.270 --> 01:14:39.650
In TypeScript wird das als Constraint bezeichnet.

01:14:39.730 --> 01:14:40.470
Aber im Grund geht es darum,

01:14:40.530 --> 01:14:42.030
dass du einfach vordefinierst,

01:14:42.030 --> 01:14:43.290
du hast ein paar Eigenschaften,

01:14:43.350 --> 01:14:44.450
die du sicherstellen willst.

01:14:44.930 --> 01:14:46.830
In dem Fall, was dort beim PEP484 ist,

01:14:46.870 --> 01:14:48.110
mit diesem Upper-Bound, sagst du einfach,

01:14:48.690 --> 01:14:50.990
du willst die Möglichkeit haben, eine Länge zu berechnen,

01:14:51.070 --> 01:14:52.910
du willst einfach wissen, hey, da gibt es eine Size,

01:14:53.090 --> 01:14:55.210
das hat eine gewisse Längegröße,

01:14:55.290 --> 01:14:55.710
was auch immer.

01:14:56.670 --> 01:14:58.690
Spannend wäre es, ob ich dort einen String reingeben kann,

01:14:58.890 --> 01:15:00.630
weil man kann ja die Länge von einem String definieren.

01:15:00.670 --> 01:15:01.130
Ja, kannst du.

01:15:02.590 --> 01:15:05.070
Alles, was Length von irgendwas hat,

01:15:05.490 --> 01:15:05.990
ist Size.

01:15:06.030 --> 01:15:08.510
Also ich kenne keinen Python, aber ich habe diesen Code jetzt gelesen

01:15:08.510 --> 01:15:10.890
und weiß sofort, was ich da zu erwarten habe,

01:15:11.030 --> 01:15:12.890
weil ein String muss auch

01:15:12.890 --> 01:15:14.190
eine Länge rauskriegen.

01:15:15.630 --> 01:15:16.130
Schon cool.

01:15:16.870 --> 01:15:35.130
Ja. Und das ist auch sehr interessant hier, weil also diese Type Variable, die gerade in diesem Beispiel, ich habe es zufällig auch gerade offen, benutzt wird, die wird in dieser Funktion, da wird eine Funktion definiert, die heißt longer und die nimmt zwei Variablen, x und y, die sind beide vom Typ st und der Rückgabewert ist ebenfalls st.

01:15:36.010 --> 01:15:56.170
Und das ist eine sehr interessante Sache, weil das eben bedeutet, du kannst hier zwei Sachen reingeben, die von der gleichen Sorte sind und kriegst wieder eins raus, was wieder von der gleichen Sorte ist. Aber wir sagen gar nicht genau, was das für eine Sorte ist, sondern wir sagen nur, das muss als Anforderung haben, das Minimum, was es erfüllen muss, das ist der Bound, ich muss davon die Länge abrufen können.

01:15:58.130 --> 01:16:14.550
Und das hat diese Funktion schon sehr genau spezifiziert, die Spezifikation dieser Funktion, also longer x, y ist ja erstmal sehr lose und jetzt durch diese Typvariablen und durch den Bound ist es doch relativ genau spezifiziert und auch sehr exakt, würde ich sagen.

01:16:14.850 --> 01:16:40.630
Was ich sehr spannend finde an dem Beispiel, und das ist wahrscheinlich jetzt so ein Python-Eigenwort, aber im ersten Aufruf wird dort dieser generische Typ-Parameter oder diese Type-Var ersetzt durch eine List, das ist glaube ich die eckigen Klammern, im zweiten Aufruf, da hast du geschwungene Klammern, wird es durch ein Set ersetzt, also der Typ wird durch ein Set ersetzt, aber im dritten, da ist im ersten Aufruf eckige Klammern, im zweiten Parameter sind geschwungene Klammern,

01:16:41.050 --> 01:16:44.550
da wird der Parent-Type davon eine Collection verwendet,

01:16:44.630 --> 01:16:46.630
wo du sagst, hey, okay, ist nicht List, ist nicht Set,

01:16:46.770 --> 01:16:47.670
also es könnte beides sein,

01:16:47.750 --> 01:16:50.710
du nimmst einfach was, was beide beschreibt.

01:16:51.310 --> 01:16:52.950
Finde ich cool, dass das das Typsystem so macht.

01:16:53.110 --> 01:16:56.030
Normalerweise würde TypeScript dir da vielleicht einen Fehler werfen.

01:16:56.190 --> 01:16:57.070
TypeScript würde da sagen,

01:16:57.190 --> 01:17:00.770
hey, wenn du das einmal durch einen Typ ersetzt,

01:17:00.950 --> 01:17:02.170
dann musst du auch im zweiten Parameter

01:17:02.170 --> 01:17:03.170
den gleichen Typ verwenden

01:17:03.170 --> 01:17:05.110
und so findest du aber in der Hierarchie

01:17:05.110 --> 01:17:08.090
tatsächlich einen Parent-Type, den du nutzen kannst.

01:17:08.230 --> 01:17:08.770
Das ist ziemlich geil.

01:17:10.050 --> 01:17:11.770
Also, richtig gut.

01:17:11.930 --> 01:17:13.110
Ja, das ist ziemlich schön.

01:17:16.210 --> 01:17:17.590
Also, nämlich auch so, dass ich das jetzt

01:17:17.590 --> 01:17:19.310
verwenden möchte, muss ich ganz ehrlich sagen.

01:17:19.970 --> 01:17:20.950
Ich glaube, ihr habt es so weit.

01:17:22.690 --> 01:17:23.250
Sehr gut.

01:17:23.910 --> 01:17:25.650
Viele Programmiersprachen-Features

01:17:25.650 --> 01:17:27.310
kommen ja durch Knight

01:17:27.310 --> 01:17:29.790
umgesetzt. Das ist bei Python

01:17:29.790 --> 01:17:31.070
und auch nicht anders.

01:17:31.550 --> 01:17:33.470
Viele Sachen sind einfach aus Knight durch andere

01:17:33.470 --> 01:17:34.250
Sprachen entstanden.

01:17:35.670 --> 01:17:37.510
Also, den größten Knight

01:17:37.510 --> 01:17:39.290
habe ich ja durch die Import-Signatur.

01:17:39.550 --> 01:17:41.550
das macht einfach so viel einfacher.

01:17:42.090 --> 01:17:43.490
In JavaScript ist es umgekehrt,

01:17:43.530 --> 01:17:45.930
du importierst zuerst die Einzelelemente

01:17:45.930 --> 01:17:47.030
aus dem Paket

01:17:47.030 --> 01:17:49.510
und das ist reine Ästhetik, so ist

01:17:49.510 --> 01:17:51.650
viel klarer, du spezifisierst

01:17:51.650 --> 01:17:53.630
zuerst das Paket und dann importierst du die Sachen

01:17:53.630 --> 01:17:55.510
draus, jeder Editor freut sich, wenn er das

01:17:55.510 --> 01:17:56.090
so kriegen kann.

01:17:58.010 --> 01:17:59.610
Ja, was

01:17:59.610 --> 01:18:01.270
mich noch interessieren würde hier an der Stelle,

01:18:01.530 --> 01:18:03.590
ist diese Overloads, die da mit drinstehen,

01:18:03.990 --> 01:18:04.870
das ist ja auch so eine Sache,

01:18:05.090 --> 01:18:07.430
die man nur bei den Type Annotations

01:18:07.430 --> 01:18:09.410
findet oder auch woanders, wo halt derselbe

01:18:09.410 --> 01:18:11.350
Methodenname mehrfach hintereinander

01:18:11.350 --> 01:18:13.650
definiert wird. Was macht denn das genau?

01:18:15.070 --> 01:18:15.670
Schreibst du

01:18:15.670 --> 01:18:17.510
in Python dort dann beide

01:18:17.510 --> 01:18:19.450
Methoden aus? Also implementierst du da

01:18:19.450 --> 01:18:20.670
beide Methoden oder

01:18:20.670 --> 01:18:23.710
sind es nur die Signaturen?

01:18:24.970 --> 01:18:25.590
In Python musst du

01:18:25.590 --> 01:18:27.530
dich da anstrengen dafür. Das hat ja nicht mal viel

01:18:27.530 --> 01:18:29.450
mit, ja es hat vielleicht schon

01:18:29.450 --> 01:18:31.510
was mit Types zu tun, aber

01:18:31.510 --> 01:18:33.470
also so richtiges

01:18:33.470 --> 01:18:35.610
Overloading gibt es ja gar nicht in Python.

01:18:35.610 --> 01:18:37.550
Du fügst eine weitere Signatur

01:18:37.550 --> 01:18:39.370
hinzu zur Methode. Ja genau, was macht denn

01:18:39.370 --> 01:18:41.690
Aber du hast doch nicht zwei Funktionen,

01:18:41.770 --> 01:18:42.690
du hast zwei Signaturen.

01:18:43.470 --> 01:18:45.510
Du hast eine Funktion, die,

01:18:46.150 --> 01:18:46.790
also es ist so,

01:18:47.530 --> 01:18:49.370
der ganz

01:18:49.370 --> 01:18:51.670
grundlegende Prozess ist, dass eine Funktion

01:18:51.670 --> 01:18:53.170
in Python eine Variable ist,

01:18:54.010 --> 01:18:55.790
die halt ein

01:18:55.790 --> 01:18:57.070
Funktionssubjekt enthält.

01:18:57.550 --> 01:18:59.810
Und diese Variable hat einen Namen und diesen Namen,

01:18:59.970 --> 01:19:01.410
der ist eindeutig, den kannst du nur einmal geben.

01:19:01.530 --> 01:19:03.670
Und zu diesem Namen kannst du auch nur diese eine Funktion geben.

01:19:04.430 --> 01:19:05.370
Was du jetzt aber machst,

01:19:05.670 --> 01:19:07.450
um Überladung zu machen,

01:19:07.450 --> 01:19:09.230
und ich erkläre es gleich noch für die Zuhörer,

01:19:09.370 --> 01:19:11.190
ist, dass

01:19:11.190 --> 01:19:13.030
du sagst, du definierst

01:19:13.030 --> 01:19:15.070
eine Basismethode und der fügst du

01:19:15.070 --> 01:19:17.250
dann eine weitere Signatur hinzu.

01:19:17.250 --> 01:19:19.150
Und wenn diese, da ist dann eben so ein

01:19:19.150 --> 01:19:21.170
durch Dekoratoren

01:19:21.170 --> 01:19:23.170
hast du so einen Mechanismus, der diese Signaturen

01:19:23.170 --> 01:19:25.190
entsprechend überprüft. So, was ist

01:19:25.190 --> 01:19:26.850
Überladung überhaupt und was erreicht man damit?

01:19:27.970 --> 01:19:29.290
Überladung ist, wenn

01:19:29.290 --> 01:19:31.130
du eine Funktion, also ganz

01:19:31.130 --> 01:19:33.170
klassisch aus dem Java-Umfeld, wenn du eine Funktion

01:19:33.170 --> 01:19:34.770
hast, die heißt add

01:19:34.770 --> 01:19:37.090
und die definierst du für float und float und dann

01:19:37.090 --> 01:19:39.030
kommt hinterher wieder ein float raus.

01:19:39.370 --> 01:19:49.910
Dann funktioniert die ganz einwandfrei für Floats, aber du kannst damit nicht Ints adden, kannst keine Integer addieren, weil der Compiler dir sagt, ich habe die Funktion gefunden, aber die geht nur für Floats.

01:19:50.470 --> 01:20:00.910
Was du jetzt in Java machst, ist, du schreibst eine zweite Funktion, die auch Add heißt, aber die eine andere Signatur hat und die wird durch das Kompilat eher zu einer anderen Funktion.

01:20:01.850 --> 01:20:03.330
Das heißt, zum Zeitpunkt des

01:20:03.330 --> 01:20:05.450
Kompilierens kann der Compiler sagen, ah, du meintest

01:20:05.450 --> 01:20:07.450
diese Funktion mit der Signatur

01:20:07.450 --> 01:20:09.490
oder du meintest diese Funktion mit der

01:20:09.490 --> 01:20:10.930
Signatur. Und das geht

01:20:10.930 --> 01:20:13.370
auch in TypeScript, wenn ich mich recht erinnere,

01:20:14.050 --> 01:20:15.170
dass du überladene

01:20:15.170 --> 01:20:17.390
Methoden hast, die dann eben durch

01:20:17.390 --> 01:20:19.590
den Compiler zum Zeitpunkt des Compilens

01:20:19.590 --> 01:20:21.630
die richtige

01:20:21.630 --> 01:20:23.090
Zuweisung bekommen. Die sind dann im

01:20:23.090 --> 01:20:25.030
JavaScript-Kompilat, heißen die dann unterschiedlich,

01:20:25.470 --> 01:20:26.470
weil die eben da unterschiedlich sind.

01:20:26.470 --> 01:20:28.210
Das ist genau der Unterschied.

01:20:29.770 --> 01:20:40.110
Nein, ein Overload in TypeScript ist im Grund nur eine andere Funktionssignatur über der tatsächlichen.

01:20:40.110 --> 01:20:47.030
Du musst mindestens zwei angeben. Eine, die dem Typsystem mitgeteilt wird als Nutzungssignatur

01:20:47.030 --> 01:20:51.150
und eine, die du verwenden kannst, um tatsächlich die Funktion zu implementieren.

01:20:51.610 --> 01:20:53.330
Und dann kannst du so viele Overload schreiben, wie du willst.

01:20:53.550 --> 01:20:58.230
Und du hast dort einfach unterschiedliche Aufrufe, durch die du durchgehen kannst.

01:20:58.370 --> 01:21:01.550
aber im Endeffekt wird nur eine Methode aufgerufen

01:21:01.550 --> 01:21:02.910
oder eine Funktion aufgerufen.

01:21:03.950 --> 01:21:05.270
Deswegen habe ich genauso nachgefragt,

01:21:05.410 --> 01:21:06.150
weil ich bin mir nicht sicher,

01:21:06.230 --> 01:21:07.350
wie das jetzt in Python funktioniert,

01:21:07.830 --> 01:21:09.250
weil es ist spannend.

01:21:10.530 --> 01:21:12.130
Es hat Führungslieder.

01:21:12.970 --> 01:21:13.130
Okay.

01:21:13.570 --> 01:21:13.710
Genau.

01:21:14.430 --> 01:21:15.530
In Python ist es ein bisschen anders.

01:21:15.670 --> 01:21:17.610
In Python musst du das eben über Dekoratoren machen,

01:21:17.690 --> 01:21:20.110
weil du diesen Namen nicht mehrfach haben darfst.

01:21:20.550 --> 01:21:22.410
Und was da im Wesentlichen passiert ist,

01:21:22.410 --> 01:21:26.130
du sagst, wenn die Methode aufgerufen wird

01:21:26.130 --> 01:21:28.470
zwei Variablen oder mit

01:21:28.470 --> 01:21:30.450
Argumenten, die

01:21:30.450 --> 01:21:32.310
dieser Signatur entsprechen, dann rufe bitte

01:21:32.310 --> 01:21:34.430
diese Subsignatur

01:21:34.430 --> 01:21:36.410
auf. Also du fügst da quasi

01:21:36.410 --> 01:21:38.530
eine weitere Funktion hinzu, die nur in bestimmten

01:21:38.530 --> 01:21:40.350
Fällen aufgerufen wird. Aber das ist

01:21:40.350 --> 01:21:42.410
was, was zur Laufzeit passiert. Also zur Laufzeit

01:21:42.410 --> 01:21:44.570
wird

01:21:44.570 --> 01:21:45.990
dann entschieden, welche

01:21:45.990 --> 01:21:48.350
Submethode

01:21:48.350 --> 01:21:50.150
aufgerufen wird. Das ist im Wesentlichen

01:21:50.150 --> 01:21:52.390
ein Match Case,

01:21:53.090 --> 01:21:54.030
der da vorsteht.

01:21:54.490 --> 01:21:56.610
Ich weiß nicht, ob das im Typing-Zusammenhang

01:21:56.610 --> 01:21:58.170
nicht was anderes ist. Also ich meine, es gibt diese

01:21:58.170 --> 01:22:00.290
Overload-Geschichten vielleicht

01:22:00.290 --> 01:22:02.450
in Klassen, aber ich meine hier

01:22:02.450 --> 01:22:04.570
auch bei Funktionen,

01:22:04.570 --> 01:22:06.150
wenn ich jetzt einfach das sozusagen für diese

01:22:06.150 --> 01:22:08.490
Typ-Annotation verwenden will, dann ist es

01:22:08.490 --> 01:22:10.550
soweit ich sehen kann auch so. Es gibt die Funktion einmal,

01:22:11.450 --> 01:22:11.630
aber

01:22:11.630 --> 01:22:13.990
ich kann halt viele sozusagen

01:22:13.990 --> 01:22:15.710
mit Overload dekorierten

01:22:15.710 --> 01:22:18.550
Funktionen haben, die keine Implementationen haben,

01:22:18.970 --> 01:22:20.170
aber wo ich sozusagen nur

01:22:20.170 --> 01:22:22.270
quasi die unterschiedlichen

01:22:22.270 --> 01:22:24.310
möglichen Arten

01:22:24.310 --> 01:22:26.230
wie ich das, wie das aufrufen

01:22:26.230 --> 01:22:28.130
werden kann, halt annotiere, weil ich das nicht in

01:22:28.130 --> 01:22:30.130
eine Annotation schreiben kann, weil geht halt

01:22:30.130 --> 01:22:31.210
nicht. Und

01:22:31.210 --> 01:22:34.070
ja. Ach so, okay.

01:22:34.310 --> 01:22:35.770
Da gibt es zwei, also es gibt

01:22:35.770 --> 01:22:37.970
mehrere Overload

01:22:37.970 --> 01:22:39.850
Dinge, denke ich.

01:22:40.510 --> 01:22:41.190
Genau, also das

01:22:41.190 --> 01:22:44.070
ist blöd, ja. Es ist blöd, dass

01:22:44.070 --> 01:22:46.070
diese Sachen in unterschiedlichen Sprachen

01:22:46.070 --> 01:22:46.850
unterschiedliche Dinge bedeuten.

01:22:49.850 --> 01:22:52.090
Also wenn ich der Kaiser wäre,

01:22:52.090 --> 01:22:52.710
dann wäre das anders.

01:22:54.310 --> 01:23:10.070
Also das ist tatsächlich was, was ich vermisst habe an Python, als ich zu Python gekommen bin aus Java. In Java kannst du sagen, ich habe hier eine Funktion, die heißt Add und die nimmt Integer und ich habe eine Funktion Add, die nimmt Strings und ich habe eine Funktion Add, die nimmt, was weiß ich, Listen.

01:23:10.290 --> 01:23:12.670
Und die machen sehr unterschiedliche Dinge, aber im Endeffekt

01:23:12.670 --> 01:23:14.510
das gleiche Semantische. Die fügen die

01:23:14.510 --> 01:23:16.650
aneinander. Und die heißen

01:23:16.650 --> 01:23:18.050
gleich, weil die das gleiche machen.

01:23:18.550 --> 01:23:20.170
Und sowas gibt es in Python nicht, weil in Python

01:23:20.170 --> 01:23:21.390
musste jedes Mal

01:23:21.390 --> 01:23:24.250
einen neuen Namen haben dafür

01:23:24.250 --> 01:23:25.170
oder einen neuen Scope oder so.

01:23:25.690 --> 01:23:27.850
Und dafür gibt es Single Dispatch.

01:23:29.910 --> 01:23:30.930
Ja, das hat

01:23:30.930 --> 01:23:33.090
damit zu tun, dass

01:23:33.090 --> 01:23:34.910
es möglich ist, dass du

01:23:34.910 --> 01:23:36.950
den gleichen Namen mehrmals vergeben kannst.

01:23:38.030 --> 01:23:39.230
Ja, weil die beim Kompilieren

01:23:39.230 --> 01:23:41.430
die Namen weg sind beim Kompilieren.

01:23:41.450 --> 01:23:42.530
Nein, nein, weil die

01:23:42.530 --> 01:23:45.170
Funktionssignaturen Typen haben.

01:23:45.730 --> 01:23:47.210
Nein, weil die Funktionssignaturen Typen haben.

01:23:47.350 --> 01:23:49.050
Weil Java die Typen

01:23:49.050 --> 01:23:51.410
erfordert

01:23:51.410 --> 01:23:53.330
und dadurch ist

01:23:53.330 --> 01:23:55.350
einfach genug Unterschied da, um das

01:23:55.350 --> 01:23:56.270
zu identifizieren können.

01:23:57.230 --> 01:23:58.670
Genau, es sind unterschiedliche Funktionen.

01:23:58.790 --> 01:24:01.230
Also die Funktion addIntInt ist eine andere Funktion

01:24:01.230 --> 01:24:03.190
als die Funktion addFloatFloat.

01:24:03.990 --> 01:24:09.050
Und darum ist natürlich in JavaScript und Python

01:24:09.050 --> 01:24:11.810
halt komplett anders, weil im Endeffekt hast du halt nur

01:24:11.810 --> 01:24:13.330
eine Funktion mit ein paar Parametern.

01:24:13.490 --> 01:24:15.450
Und die Typen sind ja, wie wir mitbekommen haben,

01:24:15.590 --> 01:24:17.030
eigentlich wurscht.

01:24:17.210 --> 01:24:17.850
Die sind dann weg.

01:24:18.350 --> 01:24:20.090
Ja, zur Laufzeit auf jeden Fall.

01:24:20.370 --> 01:24:23.130
Aber diesen Mechanismus, den kriegst du hin,

01:24:23.150 --> 01:24:24.270
der heißt Single Dispatch.

01:24:24.690 --> 01:24:27.030
From Functools import Single Dispatch.

01:24:27.110 --> 01:24:27.870
PEP 443.

01:24:29.070 --> 01:24:30.930
Das, was ihr beschrieben habt,

01:24:31.110 --> 01:24:32.010
das heißt Overload,

01:24:32.750 --> 01:24:34.650
das ist ja was ganz anderes. Python lang

01:24:34.650 --> 01:24:34.950
util.

01:24:37.310 --> 01:24:37.770
Okay.

01:24:38.770 --> 01:24:40.810
Ich hab's jetzt hier aus, von Typing.

01:24:41.730 --> 01:24:42.790
Also, so wie ich

01:24:42.790 --> 01:24:44.710
das gesehen hab, es gibt auch so ein sehr schönes

01:24:44.710 --> 01:24:46.170
Beispiel dafür, das ist auch aus dem

01:24:46.170 --> 01:24:48.670
Fluent Python Buch, hab ich das

01:24:48.670 --> 01:24:50.690
da, also das ist halt

01:24:50.690 --> 01:24:52.570
so ein Beispiel für Methoden, die halt

01:24:52.570 --> 01:24:54.550
eigentlich in, also, die hat auch so ein

01:24:54.550 --> 01:24:55.910
Problem, dass man mit Type

01:24:55.910 --> 01:24:57.530
Annotationen halt so hat,

01:24:58.110 --> 01:24:59.530
beschreiben nämlich, dass man

01:24:59.530 --> 01:25:01.830
die Typannotationen nicht so

01:25:01.830 --> 01:25:04.210
also die ist ja auch eine Sprache, ist halt eine andere

01:25:04.210 --> 01:25:05.290
Art, das hinzuschreiben

01:25:05.290 --> 01:25:08.010
und die ist halt nicht so expressiv wie Python selber.

01:25:08.170 --> 01:25:10.050
Das heißt, wenn ich jetzt Funktionen habe, wie zum Beispiel

01:25:10.050 --> 01:25:12.170
min und max, jetzt weiß ich gar nicht, ob es das

01:25:12.170 --> 01:25:14.270
in der JavaScript-Welt auch so

01:25:14.270 --> 01:25:15.630
gibt, aber die

01:25:15.630 --> 01:25:18.410
kann ich halt sehr schön in Python hinschreiben

01:25:18.410 --> 01:25:20.090
so in irgendwie so

01:25:20.090 --> 01:25:21.330
20 Zeilen oder sowas

01:25:21.330 --> 01:25:24.330
und ist sehr schön zu lesen,

01:25:24.430 --> 01:25:25.110
ist nicht kompliziert.

01:25:25.910 --> 01:25:31.330
Und die Typ-Annotation dafür ist aber sehr, sehr schwer, weil das halt so super generisch ist.

01:25:31.410 --> 01:25:36.610
Und dann kann man noch ein Callback übergeben, das halt irgendwie zum Sortieren verwendet wird und sowas.

01:25:37.230 --> 01:25:44.210
Und ja, die korrekten Type-Annotationen für Min und Max sind halt sehr viel länger als die Implementation.

01:25:44.690 --> 01:25:51.730
Und das liegt halt daran, dass man das in dieser neuen Annotationssprache halt nicht so gut hinschreiten kann.

01:25:52.330 --> 01:26:02.670
Und dafür, also da hast du dann halt so irgendwie, ich weiß nicht, zig Overloads, weil du kannst das sowieso immer nur quasi für einen Teil der, wie man das aufrufen kann, halt annotieren.

01:26:02.670 --> 01:26:09.030
Und dann musst du das halt, musst du halt zehn Dinger übereinander häufen, um das halt irgendwie abgebildet zu kriegen.

01:26:09.650 --> 01:26:16.810
Und ja, und auch in diesen Dingern sind dann halt, waren halt lange Fehler drin und die sind halt auch echt schwer zu finden.

01:26:17.050 --> 01:26:17.910
Also ja.

01:26:19.290 --> 01:26:21.810
Und die machen ja auch überhaupt gar nichts, diese Fehler, jetzt mal ganz ehrlich.

01:26:22.330 --> 01:26:41.030
Ja gut, na gut, also irgendjemand hat dann halt, es kann ja sein, du rufst das halt auf, lässt es auf eine bestimmte Art und dann läuft dein Typechecker drüber und der sagt, der spuckt dir dann halt irgendeine Fehlermeldung aus, die vollkommen unverständlich ist und das verdirbt dir halt den Vormittag oder so, weil du verstehst gar nicht, wo das Problem ist.

01:26:41.030 --> 01:26:42.890
Und dann war es halt nicht mal wirklich ein Problem,

01:26:43.050 --> 01:26:44.910
sondern es war einfach nur etwas, was halt

01:26:44.910 --> 01:26:46.930
in den Annotationen kaputt war.

01:26:47.350 --> 01:26:48.570
Und du hast es korrekt aufgerufen.

01:26:48.730 --> 01:26:49.570
Das ist ja schon ärgerlich.

01:26:50.910 --> 01:26:52.370
Also ich meine, ja, also

01:26:52.370 --> 01:26:54.190
ja, gut.

01:26:55.550 --> 01:26:56.190
Zugegeben, ja.

01:26:56.690 --> 01:26:56.930
Aber

01:26:56.930 --> 01:27:00.430
Aber was war jetzt die Lösung, Jochen?

01:27:00.430 --> 01:27:02.230
Ich habe dich jetzt unterbrochen, aber

01:27:02.230 --> 01:27:04.550
gibt es da jetzt eine Lösung dafür? Kann ich jetzt da Overload sagen?

01:27:05.230 --> 01:27:06.630
Genau. Und du kannst jetzt sozusagen,

01:27:06.730 --> 01:27:08.290
wenn du eine Funktion

01:27:08.290 --> 01:27:10.190
annotieren möchtest, aber das halt die

01:27:10.190 --> 01:27:12.230
Annotationen nicht einfach so hinschreiben kannst, dann kannst

01:27:12.230 --> 01:27:14.090
du die möglichen Arten,

01:27:14.410 --> 01:27:15.250
wie das halt, also

01:27:15.250 --> 01:27:17.810
wenn du mehrere

01:27:17.810 --> 01:27:20.330
Annotationen hinschreiben musst

01:27:20.330 --> 01:27:21.910
für die Funktion, kannst du das per Overload

01:27:21.910 --> 01:27:23.690
hinschreiben. Hast dann halt der

01:27:23.690 --> 01:27:26.030
Methoden-Body oder Funktions-Body

01:27:26.030 --> 01:27:28.090
ist einfach Ellipsis, also

01:27:28.090 --> 01:27:30.170
Punkt, Punkt, Punkt und

01:27:30.170 --> 01:27:32.090
genau, dann kannst du halt alle

01:27:32.090 --> 01:27:33.970
Arten, wie man das Ding halt getypt

01:27:33.970 --> 01:27:35.390
aufrufen kann, halt hinschreiben.

01:27:36.630 --> 01:27:38.330
So richtig schön sieht das aber auch nicht aus.

01:27:38.370 --> 01:27:39.170
Ne, das sieht nicht schön aus.

01:27:40.190 --> 01:27:46.390
Ich würde es zum Beispiel in TypeScript

01:27:46.390 --> 01:27:48.190
auch nicht immer verwenden.

01:27:48.570 --> 01:27:50.150
Meistens ist es ein Codespell, wenn du

01:27:50.150 --> 01:27:52.770
Methoden oder Funktionen

01:27:52.770 --> 01:27:54.570
hast, die mehr können

01:27:54.570 --> 01:27:56.870
soll, als für das, was

01:27:56.870 --> 01:27:58.270
sie beschreibt. Ja, so ein bisschen

01:27:58.270 --> 01:27:59.930
so eine Krücke, warum machen wir das dann nicht?

01:28:00.810 --> 01:28:02.550
Vielleicht, wenn man so ein Public-API-Interface

01:28:02.550 --> 01:28:04.250
hat, was unbedingt benutzt bleiben muss,

01:28:04.250 --> 01:28:05.030
aus irgendwelchen Gründen.

01:28:05.910 --> 01:28:07.490
Vielleicht für Legacy oder sowas.

01:28:07.510 --> 01:28:08.990
In JavaScript gibt es es, weil

01:28:08.990 --> 01:28:11.370
also in TypeScript gibt es das, weil du halt

01:28:11.370 --> 01:28:13.370
in JavaScript Parameter

01:28:13.370 --> 01:28:14.210
weglassen kannst

01:28:14.210 --> 01:28:16.530
oder

01:28:16.530 --> 01:28:19.270
Parameter

01:28:19.270 --> 01:28:21.470
in unterschiedlichen Positionen auch was anderes heißen

01:28:21.470 --> 01:28:23.230
und da hat TypeScript

01:28:23.230 --> 01:28:25.670
irgendeine Methode gebraucht, um das darzustellen

01:28:25.670 --> 01:28:27.470
und deswegen

01:28:27.470 --> 01:28:29.150
haben wir es. Ja, gut, wenn man

01:28:29.150 --> 01:28:31.050
Sternchen, Quark schreibt oder sowas.

01:28:31.430 --> 01:28:33.310
Also gerade dieses Ads-Beispiel von Johannes,

01:28:33.750 --> 01:28:35.210
das würde ich eigentlich jetzt

01:28:35.210 --> 01:28:36.290
in TypeScript mit

01:28:36.290 --> 01:28:38.610
mit Generics umsetzen

01:28:38.610 --> 01:28:38.770
hat.

01:28:39.990 --> 01:28:42.090
Ja gut, wenn du jetzt

01:28:42.090 --> 01:28:44.070
die Methode

01:28:44.070 --> 01:28:46.310
Add für Integer und die Methode Add für Stringen

01:28:46.310 --> 01:28:48.430
hast, musst du ja schon zwei unterschiedliche

01:28:48.430 --> 01:28:49.690
Implementierungen haben auch.

01:28:50.450 --> 01:28:51.950
Also an irgendeiner Stelle musst du ja deine

01:28:51.950 --> 01:28:52.990
Implementierung verzweigen.

01:28:54.070 --> 01:28:55.610
Nicht in

01:28:55.610 --> 01:28:58.350
JavaScript. Ja, wenn du Plus verwendest,

01:28:58.450 --> 01:29:00.170
okay, aber dann musst du das Plus irgendwo hin

01:29:00.170 --> 01:29:02.010
verzweigen, weil das macht ja sehr unterschiedliche Dinge.

01:29:03.190 --> 01:29:03.350
Ja.

01:29:04.510 --> 01:29:06.130
Dann könnte ich das dann dann Etto überschreiben.

01:29:06.290 --> 01:29:08.050
Ja, ja.

01:29:09.710 --> 01:29:10.150
Ja.

01:29:10.910 --> 01:29:12.390
Was mir noch

01:29:12.390 --> 01:29:14.250
fehlt, wir haben schon relativ viel

01:29:14.250 --> 01:29:16.230
gesagt, was ist sowas wie, ich glaube es ist eben

01:29:16.230 --> 01:29:18.410
schon einmal gefallen, sowas wie rekursive Types oder sowas.

01:29:18.530 --> 01:29:20.350
Wenn ich zum Beispiel einen Jason-Type definiere.

01:29:20.850 --> 01:29:22.030
Hier, sag doch nicht sowas.

01:29:24.750 --> 01:29:25.530
Kapitel 7.

01:29:27.970 --> 01:29:30.210
Bin ich ja noch weit entfernt von Kapitel 7.

01:29:33.230 --> 01:29:34.830
Ja, also rekursive Types

01:29:34.830 --> 01:29:37.870
rekursive Types ist schon

01:29:37.870 --> 01:29:39.010
nötig. Wenn du jetzt zum Beispiel

01:29:39.010 --> 01:29:41.110
eine Liste definieren willst, eine einfach

01:29:41.110 --> 01:29:43.030
verkettete Liste, dann hast du dort

01:29:43.030 --> 01:29:45.070
einen Knoten und du verweist auf den nächsten

01:29:45.070 --> 01:29:46.390
Knoten.

01:29:48.190 --> 01:29:49.110
Aber das ist eigentlich

01:29:49.110 --> 01:29:50.830
nur ein Typsystem-Fu, also du musst

01:29:50.830 --> 01:29:53.130
irgendwie die Möglichkeit

01:29:53.130 --> 01:29:54.730
haben, dass du Typen definieren kannst,

01:29:54.730 --> 01:29:56.810
die sich selbst

01:29:56.810 --> 01:29:59.090
referenzieren können, wenn nötig.

01:29:59.390 --> 01:30:00.910
Also wie JSON-Objekte

01:30:00.910 --> 01:30:01.890
oder sowas zum Beispiel tatsächlich?

01:30:02.590 --> 01:30:04.790
Zum Beispiel, ja, genau. Also in JSON

01:30:04.790 --> 01:30:05.770
kann es ja auch sein, dass du

01:30:05.770 --> 01:30:09.070
naja, schwierig.

01:30:09.630 --> 01:30:10.830
Ja, eine Liste von Objekten habe,

01:30:10.930 --> 01:30:12.730
in denen andere Listen stecken, die wieder irgendwie

01:30:12.730 --> 01:30:14.130
Teugs haben oder so. Ja, genau.

01:30:15.010 --> 01:30:16.170
Oder ein Array von Arrays,

01:30:17.170 --> 01:30:18.050
wenn du schon dabei bist.

01:30:19.110 --> 01:30:20.390
Aber ich habe eben mal mit

01:30:20.390 --> 01:30:22.350
jemandem vom TypeScript-Team gesprochen,

01:30:22.490 --> 01:30:23.610
bezüglich rekursiven Typen.

01:30:25.710 --> 01:30:26.390
Das ist meistens

01:30:26.390 --> 01:30:28.790
Implementierungsdatei, wie tief der Compiler

01:30:28.790 --> 01:30:30.530
dort denn gehen kann. Also was sind die,

01:30:32.130 --> 01:30:32.430
wie

01:30:32.430 --> 01:30:34.110
ist der Compiler entwickelt?

01:30:34.790 --> 01:30:37.490
dass er bald genug sagen kann, hey, da stoppe ich jetzt

01:30:37.490 --> 01:30:39.590
und passe nicht mehr weiter. Also wie geht der Compiler

01:30:39.590 --> 01:30:40.150
mit der Regression?

01:30:41.150 --> 01:30:42.190
Typsysteme können das eigentlich.

01:30:42.690 --> 01:30:45.470
Also auch in der IDE, ich weiß nicht, bei JSON-Type

01:30:45.470 --> 01:30:47.230
oder sowas, bis wie viel Level-Tief

01:30:47.230 --> 01:30:49.450
darf der denn gucken, ob das noch

01:30:49.450 --> 01:30:49.710
stimmt?

01:30:51.830 --> 01:30:53.510
Und da werden es auch immer besser.

01:30:53.610 --> 01:30:54.450
Das ist der Mathematik-Egal.

01:30:55.550 --> 01:30:59.350
Das ist der Mathematik-Egal, die guckt

01:30:59.790 --> 01:31:03.050
Ja.

01:31:04.190 --> 01:31:04.630
Genau.

01:31:04.790 --> 01:31:13.190
Ja, da kommt dann wieder darauf an, welche Art von Mathematik, wenn man den konstruktiven Zweig anhängt. Das gibt es gar nicht.

01:31:13.190 --> 01:31:25.590
Wenn du schon in der Grundvorlesung, also ich habe ja eine mathematische Ausbildung genossen an der Universität, da werden dann die natürlichen Zahlen nochmal definiert und die werden rekursiv definiert.

01:31:25.590 --> 01:31:27.290
Da gibt es eigentlich nur eine natürliche Zahl.

01:31:27.370 --> 01:31:29.330
Das ist die 0 oder die 1, je nachdem, wo du anfangen willst.

01:31:30.250 --> 01:31:33.150
Und dann sagt man einfach, jede Zahl hat einen Nachfolger

01:31:33.150 --> 01:31:35.510
und zack, hast du alle natürlichen Zahlen beisammen.

01:31:36.290 --> 01:31:38.750
Also es geht schon weit rein mit der Rekursion

01:31:38.750 --> 01:31:41.490
und die geht auch weit genug in der Mathematik.

01:31:43.190 --> 01:31:47.130
Ja, ich weiß nicht, haben wir noch?

01:31:47.170 --> 01:31:48.570
Ah, was mir noch einfällt, genau.

01:31:49.670 --> 01:31:52.950
Das schließt so ein bisschen an das Pidentik-Thema von eben an.

01:31:53.970 --> 01:31:55.490
Ich meine, das ist ja jetzt etwas, was man, also

01:31:55.490 --> 01:31:57.990
die Typen werden ja

01:31:57.990 --> 01:31:59.670
zur Laufzeit ignoriert

01:31:59.670 --> 01:32:00.970
in Python, aber

01:32:00.970 --> 01:32:03.710
nicht immer und man müsste es auch nicht, weil

01:32:03.710 --> 01:32:06.010
im Grunde kann man rausfinden,

01:32:06.310 --> 01:32:07.430
wie die Annotationen sind

01:32:07.430 --> 01:32:09.750
und es gibt halt auch Software, die das macht,

01:32:09.890 --> 01:32:11.050
wie zum Beispiel Pydentic.

01:32:12.730 --> 01:32:13.370
Ja, oder MyPy.

01:32:13.450 --> 01:32:16.350
Oder FastAPI. Oder FastAPI.

01:32:16.350 --> 01:32:17.810
Ja, genau.

01:32:18.290 --> 01:32:20.250
Gibt es sowas eigentlich in TypeScript auch?

01:32:21.130 --> 01:32:22.030
Weil, ich meine, gut,

01:32:22.310 --> 01:32:27.750
Das wird ja kompiliert zu JavaScript, aber es gibt ja jetzt auch, glaube ich, Interpreter, die direkt TypeScript interpretieren.

01:32:27.850 --> 01:32:30.190
So Deno oder sowas macht das, glaube ich. Ich weiß nicht so genau.

01:32:30.710 --> 01:32:31.750
Könnte das ja im Grunde genommen tun.

01:32:32.250 --> 01:32:38.210
Das ist ja ein weitverbreiteter Irrglaube, dass Deno direkt TypeScript interpretiert.

01:32:38.450 --> 01:32:43.690
Deno hat nur einen TypeScript-Compiler inkludiert und kompiliert TypeScript, bevor er das JavaScript ausführt.

01:32:44.470 --> 01:32:50.990
Also tatsächlich, ich sage mal, im JavaScript-Bereich reden wir eher von unterschiedlichen Typsystemen, die existieren.

01:32:51.930 --> 01:32:54.110
wie Flow-Type ist zum Beispiel

01:32:54.110 --> 01:32:55.990
eins, das sehr, sehr optisch sehr, sehr ähnlich

01:32:55.990 --> 01:32:57.370
ist zu dem, was TypeScript

01:32:57.370 --> 01:32:59.690
zur Verfügung stellt, aber halt

01:32:59.690 --> 01:33:01.170
in den Nansen unterschiedlich ist.

01:33:01.730 --> 01:33:02.910
Oder eben TypeScript

01:33:02.910 --> 01:33:05.530
und das sind auch schon die populärsten.

01:33:05.610 --> 01:33:07.450
Der Clojure-Compiler hat einmal ähnlich funktioniert.

01:33:08.170 --> 01:33:09.950
Coffee-Script gab es früher.

01:33:10.650 --> 01:33:11.810
Ja, Coffee-Script ist aber sogar

01:33:11.810 --> 01:33:12.730
eine eigene Programmiersprache.

01:33:14.050 --> 01:33:15.750
Ja, aber komplett, also ich meine.

01:33:19.650 --> 01:33:20.830
Gleiche Historie.

01:33:21.930 --> 01:33:43.270
Ähnlich, ähnlich. Da gibt es auch einen wichtigen Punkt, weil wie Typen definiert werden in JavaScript, das ist ja eigentlich nicht dem TypeScript-Team zu verdanken, sondern dem ECMAScript-4-Standard, der schon viel, viel älter ist, der nie umgesetzt wurde, an den sich aber alle Typsysteme jetzt irgendwie dranhalten bei der Definition des eigenen Typsystems.

01:33:43.590 --> 01:34:05.990
Ich würde eher sogar sagen, dass Action-Skript, also die Flash-Programmiersprache noch eher ähnlicher oder verwandter mit TypeScript und Flow-Type ist. Aber das ist es dann auch. Also du hast entweder unterschiedliche Typsysteme, dann entscheidest du dich in den meisten Fällen heutzutage eh für TypeScript und dann bietet dir TypeScript eigentlich alles, was du dafür brauchst.

01:34:05.990 --> 01:34:22.550
Also du laufst da gar nicht in Gefahr, dass du irgendwie ein anderes Werkzeug nimmst. Und TypeScript versteht halt auch komplett JavaScript. Das heißt, du kannst halt dort noch mit JavaScript-Code anfangen und dich nur einmal auf die Typ-Inferenz vom TypeScript-Type-Checker verlassen.

01:34:22.550 --> 01:34:49.610
Dass du sagst, ich weiß jetzt, welche Typen du verwendest, rein in der Verwendung deines Codes. Dass du jetzt so eine retroaktive Typ-Annotation machst, macht man eher nicht. Es gibt ein paar Werkzeuge, ich könnte aber jetzt nicht den Namen dazu sagen, macht man aber aus dem Grund nicht, weil der TypeScript-Type-Checker eh gut genug ist, dass er schon sehr, sehr viel herausfindet, bevor du überhaupt irgendeine Annotation machen musst.

01:34:51.350 --> 01:34:57.730
Was ein gutes Migrations-Solis ist, ist JS-Doc, das ist eine Typ-Annotation im Kommentar,

01:34:58.210 --> 01:35:01.170
wo du einfach sagst, hey, du hast diese Funktion, die hat drei Parameter,

01:35:01.170 --> 01:35:09.170
du definierst den Typen im Kommentar und nicht im Code und das machen viele Bibliotheken,

01:35:09.950 --> 01:35:15.570
das machen sehr viele alte JavaScript-Bibliotheken, wie zum Beispiel Lodash oder Underscore schon

01:35:15.570 --> 01:35:20.290
und TypeScript kann mit dem umgehen, also TypeScript kann auch Typ-Informationen aus diesen Kommentaren lesen

01:35:20.290 --> 01:35:26.110
und hat halt so weit mehr Kompatibilität mit dem gesamten Ökosystem,

01:35:26.210 --> 01:35:29.650
als wenn sie darauf bestehen würden, dass sie nur die Typen verwenden, die du annotierst.

01:35:32.270 --> 01:35:37.430
Okay, aber so ein richtiges Äquivalent zu dem, was der Jochen gefragt oder gesagt hat,

01:35:37.490 --> 01:35:38.210
gibt es nicht wirklich.

01:35:38.310 --> 01:35:41.050
Zur Laufzeit hast du nicht wirklich mehr die Typinformation.

01:35:42.630 --> 01:36:05.250
Also zur Laufzeit, es gibt Bibliotheken, die fügen Typinformation zur Laufzeit hinzu und leiten dadurch TypeScript-Typen ab, aber das ist es dann schon. Also es gibt auch ein paar so Reflection-Geschichten, das ist aber alles Mumpitz, also das möchte ich nicht einmal erwähnen, weil es einfach Schwachsinn ist.

01:36:05.670 --> 01:36:07.830
Eine Sache, die aber gut ist zum Beispiel, das ist SOD.

01:36:08.050 --> 01:36:11.130
Wenn du jetzt sagst, du brauchst jetzt Typinformationen zu Laufzeit auch,

01:36:12.090 --> 01:36:17.510
dann kannst du über die SOD-Bibliothek dir deinen Typen in JavaScript definieren.

01:36:18.150 --> 01:36:19.630
Das ist aber nicht TypeScript, das ist JavaScript.

01:36:20.470 --> 01:36:24.210
Und kannst dann, wenn du diesen Typen weiter im TypeScript-Code verwenden willst,

01:36:24.210 --> 01:36:29.570
sagen, hey, leite mir jetzt aus diesem JavaScript-Konstrukt, das ich gebaut habe,

01:36:29.630 --> 01:36:33.050
das einen Typen darstellen soll, leite mir von diesem JavaScript-Konstrukt

01:36:33.050 --> 01:36:35.550
doch einen TypeScript-Typen ab, den ich weiterverwende.

01:36:35.670 --> 01:36:48.410
Und du bekommst dann zum einen einen klassischen TypeScript-Typ, den du in deinen Methodensignaturen verwenden kannst, den du annotieren kannst, wo du typechecken kannst, das funktioniert, das ist grandios gut.

01:36:49.090 --> 01:37:02.930
Parallel dazu hast du aber immer noch dieses JavaScript-Konstrukt, mit dem du erst eine Validierung empfangen kannst. Das heißt, du kannst sagen, hey, du kriegst jetzt ein Chasen von einem Backend, steckst es in den Validator rein und kriegst entweder Ergebnisse, die es nachher dem Typen entspricht, super, oder Fehlermeldungen, mit denen du umgehen kannst.

01:37:02.930 --> 01:37:04.070
und das ist eine

01:37:04.070 --> 01:37:06.450
grandiose Bibliothek.

01:37:08.370 --> 01:37:08.810
Erstens

01:37:08.810 --> 01:37:10.850
ist sie so nah an TypeScript, dass du

01:37:10.850 --> 01:37:13.070
wirklich sämtliche Dinge, die du in TypeScript schreiben kannst,

01:37:13.470 --> 01:37:15.070
auch damit umsetzen kannst

01:37:15.070 --> 01:37:16.810
und zweitens ist sie schnell,

01:37:17.630 --> 01:37:18.670
sie macht robusteren Code,

01:37:18.790 --> 01:37:21.130
ich bin total glücklich mit der, die kann ich sehr, sehr gut empfehlen.

01:37:21.310 --> 01:37:21.750
Also unbedingt.

01:37:22.790 --> 01:37:23.710
Aber prinzipiell gilt es.

01:37:23.710 --> 01:37:25.070
Okay, cool. Also ein ähnliches

01:37:25.070 --> 01:37:26.950
Verfahren. Sehr ähnlich.

01:37:27.170 --> 01:37:29.910
In Salt ist es aber so, dass du

01:37:29.910 --> 01:37:31.570
die Typen dann anfängst

01:37:31.570 --> 01:37:34.970
zu schreiben in dieser JavaScript-Welt

01:37:34.970 --> 01:37:39.190
mit den dort vorhandenen Methoden und Funktionen.

01:37:39.530 --> 01:37:40.810
Und das ist halt umgekehrt zu dem,

01:37:40.970 --> 01:37:42.490
wie es du normalerweise in TypeScript auch ist,

01:37:42.530 --> 01:37:44.190
dass du sagst, du schreibst deine Typen

01:37:44.190 --> 01:37:45.830
und die sind nach dem Kompilator einfach weg.

01:37:45.970 --> 01:37:48.630
Also TypeScript ist so eine Erased-to-JavaScript-Sprache,

01:37:49.390 --> 01:37:51.270
was auch bedeutet, wenn du es nicht zur Laufzeit haben willst,

01:37:51.410 --> 01:37:53.710
musst du in JavaScript anfangen und musst halt dem anderen weggehen.

01:37:55.090 --> 01:37:59.230
Ja, okay, aber da würde ja nicht prinzipiell was dagegen sprechen, oder?

01:37:59.230 --> 01:38:01.150
dass du von TypeScript-Typen zu

01:38:01.150 --> 01:38:02.930
JavaScript-Typen gehst. Das ist nur

01:38:02.930 --> 01:38:04.870
das Tooling, das existiert nicht.

01:38:04.970 --> 01:38:07.130
Aber das ist doch cool. Du hast auf jeden Fall

01:38:07.130 --> 01:38:08.150
das gleiche. Unbedingt zu empfehlen.

01:38:09.630 --> 01:38:10.830
Ja, unbedingt zu empfehlen.

01:38:11.070 --> 01:38:12.430
Das ist richtig, richtig cool. Finde ich super spannend.

01:38:12.950 --> 01:38:14.290
Könnte auch für mich nützlich sein.

01:38:15.630 --> 01:38:16.950
Also gerade wenn du mit

01:38:16.950 --> 01:38:19.270
Backends arbeiten musst, denen du nicht trauen kannst,

01:38:19.570 --> 01:38:21.150
herrlich. Ja, oder

01:38:21.150 --> 01:38:23.270
mit Inputs von Benutzern.

01:38:23.430 --> 01:38:25.150
Ich meine, da musst du eh immer Validierung

01:38:25.150 --> 01:38:25.930
machen, aber das

01:38:26.770 --> 01:38:27.670
kann einem ja

01:38:27.670 --> 01:38:30.050
in dem Sinne die Arbeit ein bisschen abnehmen.

01:38:30.810 --> 01:38:32.230
Naja, quasi man definiert

01:38:32.230 --> 01:38:33.810
halt, wie man gerne hätte, dass die eigene

01:38:33.810 --> 01:38:36.130
Datenstruktur aussieht und benutzt

01:38:36.130 --> 01:38:38.190
dann diese Information halt auch zur Validierung

01:38:38.190 --> 01:38:39.350
dagegen. Das ist natürlich

01:38:39.350 --> 01:38:41.650
also, ja, das ist genau eigentlich

01:38:41.650 --> 01:38:43.650
der US-Case von Pydentic auch.

01:38:45.310 --> 01:38:45.970
Ja, ja,

01:38:45.990 --> 01:38:47.470
muss man das Pydentic noch genauer anschauen.

01:38:47.470 --> 01:38:49.430
Also das hört sich zum

01:38:49.430 --> 01:38:51.270
Zeitmehr, ich habe es heute gehört, wie wir

01:38:51.270 --> 01:38:51.930
begonnen haben.

01:38:53.350 --> 01:38:54.770
Und jetzt wieder. Erklär mal, Jochen,

01:38:55.050 --> 01:38:57.570
zwischen FastAPI und Pydentic.

01:38:57.670 --> 01:39:01.770
Ach, ja, FastAPI ist sozusagen ein ...

01:39:01.770 --> 01:39:02.730
Ein Repeter-Face, fast.

01:39:02.790 --> 01:39:04.790
Ja, genau.

01:39:05.070 --> 01:39:05.910
Automatisierung bereitstellen.

01:39:05.950 --> 01:39:06.310
Ja, und Pydentic.

01:39:06.870 --> 01:39:09.650
Pydentic ist eine Bibliothek, die benutzt wird von FastAPI

01:39:09.650 --> 01:39:13.190
und die halt sozusagen ermöglicht,

01:39:13.290 --> 01:39:16.350
wenn man halt mit Typ-Annotationen sozusagen,

01:39:16.510 --> 01:39:17.930
oder der Syntax, es gibt noch mehr,

01:39:18.010 --> 01:39:19.050
weil man kann halt auch noch mehr machen

01:39:19.050 --> 01:39:21.710
als nur die Sachen, die mit Annotationen möglich sind.

01:39:21.770 --> 01:39:25.150
Man kann halt auch Validierungsfunktionen haben

01:39:25.150 --> 01:39:27.470
und Upper Limits und

01:39:27.470 --> 01:39:29.810
Lower Limits und weiß ich nicht, und ganz viel kompliziertes

01:39:29.810 --> 01:39:31.050
Zeugs halt auch mit dazu schreiben. Das geht

01:39:31.050 --> 01:39:33.450
mit den Typ-Annotationen natürlich nicht,

01:39:33.570 --> 01:39:35.630
aber wenn man einfach nur die Typ-Annotationen hinschreibt,

01:39:35.790 --> 01:39:37.470
dann passiert das halt auch, dass dann

01:39:37.470 --> 01:39:39.510
sozusagen man

01:39:39.510 --> 01:39:40.990
einen JSON nehmen kann und man hat halt

01:39:40.990 --> 01:39:43.250
eine Objektstruktur definiert mit den Typen

01:39:43.250 --> 01:39:45.050
und dann sagt man halt, hier ist das JSON,

01:39:45.930 --> 01:39:47.370
parse das mal

01:39:47.370 --> 01:39:48.570
und validiere das mal.

01:39:48.770 --> 01:39:51.190
Und wenn es nicht, dann kriegst du 422 zurück, weil da fehlt irgendwas.

01:39:51.590 --> 01:39:53.150
Wenn es nicht okay ist,

01:39:53.190 --> 01:39:55.130
kriegt man halt schöne Fehlermeldungen auch zurück, wo dann

01:39:55.130 --> 01:39:57.070
genau gesagt hat, so an der Stelle

01:39:57.070 --> 01:39:59.170
hast du gesagt, das soll ein

01:39:59.170 --> 01:40:01.050
Number sein, aber da ist eigentlich, da ist ein

01:40:01.050 --> 01:40:03.010
String oder das ist halt irgendwie,

01:40:03.070 --> 01:40:05.030
das passt sonst wie nicht, das soll eine Liste sein, aber das

01:40:05.030 --> 01:40:07.010
ist halt nicht, ja, und

01:40:07.010 --> 01:40:08.590
das ist natürlich nett. Okay, also es ist,

01:40:08.670 --> 01:40:10.090
also es ist quasi

01:40:10.090 --> 01:40:12.750
das, woraus FastAPI

01:40:12.750 --> 01:40:13.890
gebaut wird. FastAPI ist

01:40:13.890 --> 01:40:15.790
identisch via

01:40:15.790 --> 01:40:18.150
HTTP. Ja,

01:40:18.410 --> 01:40:20.250
plus es sind noch so ein paar Sachen

01:40:20.250 --> 01:40:22.510
zusätzlich dabei. Starlet ist halt

01:40:22.510 --> 01:40:24.230
irgendwie sozusagen das alles, was HTTP

01:40:24.230 --> 01:40:26.390
angeht oder so, macht da drunter

01:40:26.390 --> 01:40:27.970
die Bibliothek von Tom Christie.

01:40:28.530 --> 01:40:29.830
Also Fast API ist schon so ein bisschen,

01:40:30.270 --> 01:40:31.470
ist halt so irgendwie

01:40:31.470 --> 01:40:34.010
drei sehr coole oder drei, vier

01:40:34.010 --> 01:40:36.050
sehr coole Open-Source-Bibliotheken in einem French-Code

01:40:36.050 --> 01:40:38.090
irgendwie quasi. Noch so Routing,

01:40:38.350 --> 01:40:40.050
das hat man halt irgendwie von Flask

01:40:40.050 --> 01:40:41.410
früher kannte, als Dekorator.

01:40:41.510 --> 01:40:42.550
Ja, Flask war auch sehr alt.

01:40:43.010 --> 01:40:44.410
Ja, genau, das ist natürlich auch sehr alt.

01:40:45.890 --> 01:40:47.890
Also Stefan, wenn du Fast API schon kennst,

01:40:48.090 --> 01:40:49.970
dann weißt du auch, wie Pedantic funktioniert.

01:40:50.070 --> 01:40:50.610
Nur halt innerhalb.

01:40:52.510 --> 01:40:52.910
Genau.

01:40:53.130 --> 01:40:55.670
Also wie gesagt, ich habe den Namen in ein Architektur-Diagramm

01:40:55.670 --> 01:40:57.510
geschrieben. Also das ist meine Erfahrung damit.

01:40:59.070 --> 01:40:59.950
Reicht anscheinend.

01:41:00.190 --> 01:41:01.550
Es ist schon mehr damit gemacht als viele.

01:41:03.970 --> 01:41:04.370
Genau.

01:41:05.070 --> 01:41:05.330
Ja.

01:41:06.310 --> 01:41:07.550
Genau. Also ja, das ist

01:41:07.550 --> 01:41:09.530
auf jeden Fall auch so noch ein ganz interessanter

01:41:09.530 --> 01:41:11.430
Ding. Weil ich meine, das ist ja tatsächlich

01:41:11.430 --> 01:41:13.430
so, wie viele Leute das benutzen. Viele Leute benutzen

01:41:13.430 --> 01:41:15.430
einen TypeDict und denken, das würde passieren, dass es

01:41:15.430 --> 01:41:16.610
validiert wird. Aber es passiert halt nicht.

01:41:17.590 --> 01:41:19.170
Ja. Genau.

01:41:20.130 --> 01:41:21.470
Ja, ansonsten, ich weiß es nicht. Haben wir noch

01:41:21.470 --> 01:41:23.210
irgendwas Großes vergessen oder so, aber ich glaube

01:41:23.210 --> 01:41:24.910
ansonsten

01:41:24.910 --> 01:41:27.250
ich habe hier fast nichts mehr, was ich noch irgendwie

01:41:27.250 --> 01:41:29.310
unbedingt gerne wissen wollte.

01:41:29.690 --> 01:41:30.990
Ja, nach anderthalb

01:41:30.990 --> 01:41:33.230
Stunden alles über

01:41:33.230 --> 01:41:35.650
Typsysteme und Typen

01:41:35.650 --> 01:41:37.370
gesagt. Das ging ja relativ

01:41:37.370 --> 01:41:38.010
schnell jetzt.

01:41:39.430 --> 01:41:41.390
Für meinen Typen hat der immer noch keine Erklärung gefunden,

01:41:41.470 --> 01:41:41.850
aber sonst.

01:41:44.570 --> 01:41:45.370
So Typen wie

01:41:45.370 --> 01:41:46.950
dich, Dominik, ist schwer zu beschreiben.

01:41:46.950 --> 01:41:47.490
Das ist so.

01:41:49.990 --> 01:41:51.010
No space enough.

01:41:51.470 --> 01:41:54.810
Ja, wirklich, ich finde es schön.

01:41:55.050 --> 01:41:57.190
Stefan, hast du noch etwas, was du unbedingt loswerden wolltest?

01:41:57.970 --> 01:42:00.450
Ich glaube, ich habe jetzt noch ein anschauliches Beispiel gefunden

01:42:00.450 --> 01:42:02.010
zu Co-Varianz und Kontra-Varianz.

01:42:02.230 --> 01:42:03.970
Nachdem ich mir die Grafik so lange angeschaut habe.

01:42:04.070 --> 01:42:04.930
Ich hoffe, ich kann es erklären.

01:42:06.310 --> 01:42:11.250
Co-Varianz ist in Wirklichkeit etwas, was wir als Subtyping verstehen.

01:42:11.730 --> 01:42:14.230
Angenommen, du hast ein Lebewesen, dann hast du ein Subtyp davon,

01:42:14.330 --> 01:42:17.310
das ist ein Pflanzenfresser, dann hast du ein Subtyp davon, das ist eine Kuh.

01:42:17.310 --> 01:42:19.630
Das heißt, du wirst immer konkreter und konkreter und konkreter.

01:42:20.090 --> 01:42:22.370
Was bedeutet, wenn du irgendwo ein Lebewesen erwartest,

01:42:22.450 --> 01:42:24.050
kannst du dort einen Pflanzenfässer reinschmeißen,

01:42:24.130 --> 01:42:26.390
kannst aber auch Kühe reinschmeißen oder Schafe reinschmeißen

01:42:26.390 --> 01:42:30.050
oder Veganer, von mir aus.

01:42:31.150 --> 01:42:33.470
Und das ist Covariance.

01:42:33.790 --> 01:42:37.110
Das heißt, du kannst etwas sehr Breites akzeptieren

01:42:37.110 --> 01:42:39.750
und kannst etwas sehr Konkretes reinstopfen,

01:42:39.950 --> 01:42:40.890
wenn der Subtyp da ist.

01:42:40.890 --> 01:42:43.790
Also das heißt, ich erwarte ein Lebewesen als Type Annotation quasi.

01:42:44.270 --> 01:42:44.910
Genau, genau, genau.

01:42:45.890 --> 01:42:49.330
Jetzt hast du aber zum Beispiel eine andere Covariance,

01:42:49.430 --> 01:42:54.530
Nämlich du hast jetzt Pflanze und davon abgeleitet Gras und davon abgeleitet vielleicht Heu oder so.

01:42:54.530 --> 01:43:01.990
Und jetzt willst du eine Funktion zur Verfügung stellen, die akzeptiert Grasesser,

01:43:02.550 --> 01:43:07.410
dann kannst du dort bei den Grasessern Kühe, aber auch Pflanzenfresser reinschmeißen.

01:43:08.110 --> 01:43:16.610
Wenn du jetzt aber sagst, du akzeptierst jetzt Pflanzen,

01:43:17.150 --> 01:43:23.150
also alle die Pflanzen oder Funktionen von Entitäten,

01:43:23.350 --> 01:43:25.650
die alle Pflanzen essen können, alle Pflanzen,

01:43:26.510 --> 01:43:28.170
dann kannst du dort keine Kühe reingeben,

01:43:28.230 --> 01:43:29.430
weil Kühe können nur Gras essen.

01:43:30.530 --> 01:43:31.550
Und das ist Kontravariant.

01:43:31.550 --> 01:43:33.370
Das heißt, du hast zwar auch einen Subtypen,

01:43:33.450 --> 01:43:34.590
du hast einen sehr breiten Typen.

01:43:34.870 --> 01:43:36.870
Ich akzeptiere ja Pflanzenfresser.

01:43:37.290 --> 01:43:38.770
Allerdings kannst du keine Kühe reingeben,

01:43:38.810 --> 01:43:40.030
weil Kühe nur Gras essen dürfen.

01:43:41.150 --> 01:43:43.010
Okay, und Inverianz ist dann ganz festgesetzt,

01:43:43.110 --> 01:43:44.510
dass halt nur den einen speziellen Typ.

01:43:44.610 --> 01:43:46.310
Genau, Inverianz geht in beide Richtungen.

01:43:46.870 --> 01:43:48.690
Ja, genau. Also ich hoffe,

01:43:48.830 --> 01:43:50.230
dass das nochmal veranschaulicht.

01:43:50.870 --> 01:43:52.550
Ich glaube, wir gucken uns lieber dein Bild nochmal an.

01:43:52.650 --> 01:43:54.810
Ich hoffe, das Bild ist so anschaulich

01:43:54.810 --> 01:43:56.930
für die Leute, die rausgestiegen sind.

01:43:58.050 --> 01:43:58.830
Ja, aber

01:43:58.830 --> 01:44:00.710
wir werden sicherlich ganz viele E-Mails

01:44:00.710 --> 01:44:02.850
kriegen und das in den nächsten vier Folgen alles nochmal

01:44:02.850 --> 01:44:04.230
genau erklären.

01:44:04.770 --> 01:44:07.750
Ja, okay, wenn da eine Erklärung dabei ist.

01:44:08.250 --> 01:44:09.730
Hallo bei peistenpodcast.de.

01:44:10.610 --> 01:44:12.610
Wir haben aber noch gar nicht ganz fertig,

01:44:12.690 --> 01:44:15.970
weil wir möchten ja noch unseren Pick der Woche, glaube ich, auswählen.

01:44:17.050 --> 01:44:17.650
Ich fange mal an.

01:44:18.710 --> 01:44:20.250
Stefan, weißt du denn, was ein Pick ist?

01:44:21.130 --> 01:44:23.210
Ja, also müssen wir jetzt irgendeinen Link raussuchen,

01:44:23.310 --> 01:44:24.370
den er total grandios findet.

01:44:24.650 --> 01:44:25.030
Ja, genau.

01:44:25.470 --> 01:44:27.230
Irgendwas Schönes zeigen.

01:44:27.230 --> 01:44:29.790
Ja, meistens nennen wir Python-Module, aber das ...

01:44:29.790 --> 01:44:31.710
Ich nehme tatsächlich, ja, auch nicht immer.

01:44:32.210 --> 01:44:34.490
Ich nehme tatsächlich diesmal eins von

01:44:34.490 --> 01:44:36.490
Simon Willison und zwar das LLM. Ich glaube, das haben wir

01:44:36.490 --> 01:44:37.950
bei einer der Machine Learning Folgen

01:44:37.950 --> 01:44:40.570
in Shownotes irgendwo

01:44:40.570 --> 01:44:42.210
gehabt, aber es ist tatsächlich

01:44:42.210 --> 01:44:44.190
bei mir ist vermehrt in Benutzung

01:44:44.190 --> 01:44:46.430
im Monkey Patch schon immer das Default, aber sonst

01:44:46.430 --> 01:44:48.210
ist es sehr, sehr schön, weil du halt

01:44:48.210 --> 01:44:50.350
ganz viele Templates und Chains von

01:44:50.350 --> 01:44:52.410
Templates direkt benutzen kannst in deiner

01:44:52.410 --> 01:44:54.410
Kommandozeile, um halt mit den verschiedenen

01:44:54.410 --> 01:44:56.350
Modellen zu sprechen direkt, die

01:44:56.350 --> 01:44:57.730
du da haben willst.

01:44:58.710 --> 01:45:00.110
Und es ist toll, wenn man

01:45:00.110 --> 01:45:01.950
harte Instruktionen gibt, dann so die

01:45:01.950 --> 01:45:04.170
Standard-Persönlichkeit des

01:45:04.170 --> 01:45:06.570
antwortenden LLMs irgendwie

01:45:06.570 --> 01:45:08.570
so ein bisschen gerade zu rücken

01:45:08.570 --> 01:45:10.630
auf das, was man selber gerne als Antwort hätte.

01:45:12.550 --> 01:45:14.630
Such irgendwie die Leute gut aus,

01:45:14.710 --> 01:45:16.250
mit denen du sprichst, das wollte ich damit sagen.

01:45:16.610 --> 01:45:20.170
Und dann leitest du uns ein, Dominik.

01:45:21.390 --> 01:45:22.530
Weiterhin viel Spaß

01:45:22.530 --> 01:45:24.310
bei den nächsten Pics, wollte ich noch sagen.

01:45:26.570 --> 01:45:26.970
Ja.

01:45:27.690 --> 01:45:29.070
Ja, was hast du denn gepickt, Jochen?

01:45:29.650 --> 01:45:31.990
Was wollte ich? Ah, genau. Ich dachte mir

01:45:31.990 --> 01:45:33.610
so, naja, vielleicht auch ein Buch mal.

01:45:34.450 --> 01:45:35.890
Und zwar eins, das ich nicht gelesen

01:45:35.890 --> 01:45:37.970
habe. Aber wo man

01:45:37.970 --> 01:45:39.870
das alles nachlesen kann, kann man auch

01:45:39.870 --> 01:45:40.970
die Antworten, wenn man

01:45:40.970 --> 01:45:43.770
drauf gekommen ist, wie das sein muss, an uns schicken.

01:45:44.130 --> 01:45:45.750
Und zwar The Little

01:45:45.750 --> 01:45:47.770
Typer ist ein Buch, das

01:45:47.770 --> 01:45:49.670
ich habe es versucht zu lesen. Es ist irgendwie, ich habe

01:45:49.670 --> 01:45:50.730
dann zwischendurch aufgegeben.

01:45:51.470 --> 01:45:53.730
Das muss ich sagen, wie Experiment mit Types

01:45:53.730 --> 01:45:54.250
entbeißen.

01:45:55.970 --> 01:45:57.450
Aber da steht

01:45:57.450 --> 01:45:59.350
da steht das, glaube ich, alles ganz genau drin, wenn man das

01:45:59.350 --> 01:46:01.330
wissen will. Und ah gut, vielleicht

01:46:01.330 --> 01:46:02.670
nochmal was Praktisches, weil

01:46:02.670 --> 01:46:04.150
ja,

01:46:05.030 --> 01:46:06.790
das ist ja doch nicht irgendwie

01:46:06.790 --> 01:46:08.730
was für alle wahrscheinlich.

01:46:09.390 --> 01:46:10.990
Doku ist ganz nett, auch

01:46:10.990 --> 01:46:12.990
nicht Python, sondern Go.

01:46:13.930 --> 01:46:14.250
Geschichte,

01:46:15.270 --> 01:46:17.490
Heroku hatte ja in letzter Zeit so ein bisschen Probleme

01:46:17.490 --> 01:46:19.010
und

01:46:19.010 --> 01:46:21.370
ist nicht mehr so richtig

01:46:21.370 --> 01:46:23.230
irgendwie der Platz, wo man vielleicht so mal so,

01:46:23.410 --> 01:46:25.170
also früher hat man das ja, wenn man irgendwas

01:46:25.170 --> 01:46:27.150
mal eben deployen wollte,

01:46:27.210 --> 01:46:28.910
hat man das oft dann bei Heroku oder so

01:46:28.910 --> 01:46:31.370
getan, weil das halt sehr einfach war,

01:46:31.530 --> 01:46:33.270
aber das geht

01:46:33.270 --> 01:46:33.870
irgendwie nicht mehr.

01:46:35.730 --> 01:46:37.330
Wo würdest du das jetzt machen, Jochen?

01:46:38.110 --> 01:46:38.710
Also meine

01:46:38.710 --> 01:46:41.190
Lösung dafür ist ja, dass ich das halt einfach,

01:46:41.330 --> 01:46:42.290
ich habe da so meine Standard

01:46:42.290 --> 01:46:44.810
Ansible-Dinger.

01:46:44.810 --> 01:46:45.950
Ja, okay, gut. Also du

01:46:45.950 --> 01:46:48.870
bist vom, dir ist Heroku

01:46:48.870 --> 01:46:51.130
zu kompliziert geworden und deshalb hast du

01:46:51.130 --> 01:46:52.670
jetzt deine eigene Hosting-Lösung gebaut.

01:46:52.670 --> 01:46:54.070
Ja, leider, ja.

01:46:54.250 --> 01:46:55.970
Ist natürlich keine Option, die jetzt viele

01:46:55.970 --> 01:46:57.790
dazu hören. Genau, also das kann ich auch

01:46:57.790 --> 01:46:59.250
nicht unbedingt empfehlen, das ist

01:46:59.250 --> 01:47:01.850
unerwartet kompliziert,

01:47:01.950 --> 01:47:03.810
aber bei mir geht's jetzt daher, hab ich das Problem

01:47:03.810 --> 01:47:05.830
nicht mehr. Und ich mach ja auch

01:47:05.830 --> 01:47:07.630
kein Docker oder so, sondern ich deploy da

01:47:07.630 --> 01:47:08.770
dann direkt irgendwie.

01:47:10.430 --> 01:47:11.350
Knallhart, bare metal.

01:47:11.670 --> 01:47:13.470
Ja, genau. Und

01:47:13.470 --> 01:47:15.950
bei

01:47:15.950 --> 01:47:17.470
Doku hat man dann halt irgendwie sowas,

01:47:17.890 --> 01:47:19.810
wo man dann so ähnlich wie mit Heroku einfach

01:47:19.810 --> 01:47:21.710
man hat halt so ein POC-File und dann

01:47:21.710 --> 01:47:23.770
kann man das einfach direkt und da auch

01:47:23.770 --> 01:47:25.810
also wenn man einen Docker-Container bauen kann, kann man

01:47:25.810 --> 01:47:27.890
Docker-Container dahin deployen und die laufen

01:47:27.890 --> 01:47:29.910
dann unter Subdomänen direkt mit

01:47:29.910 --> 01:47:31.770
HTTPS und so. Arbeitet das sogar mit Heroku?

01:47:32.010 --> 01:47:32.370
Also Doku?

01:47:33.610 --> 01:47:35.810
Nee, nee, das ist also, aber du musst

01:47:35.810 --> 01:47:37.190
halt das Doku auf einem

01:47:37.190 --> 01:47:39.310
von irgendwo auf einem

01:47:39.310 --> 01:47:41.210
weiß ich nicht, auf einer virtuellen Maschine

01:47:41.210 --> 01:47:43.470
irgendeinem Dings halt deployed haben.

01:47:43.810 --> 01:47:45.890
Self-hosted Heroku. Genau, self-hosted

01:47:45.890 --> 01:47:46.710
Heroku quasi.

01:47:48.130 --> 01:47:49.830
Und genau, das ist glaube ich

01:47:49.830 --> 01:47:51.370
manchmal ganz hilfreich, sowas zu haben.

01:47:52.010 --> 01:47:52.890
Ah. Ja.

01:47:53.570 --> 01:47:55.730
Okay, dann schließe ich mich da

01:47:55.730 --> 01:47:57.670
direkt mal an, weil in dem Fall habe ich drei

01:47:57.670 --> 01:47:58.050
Picks.

01:47:59.650 --> 01:48:01.690
Der erste ist Vercel.

01:48:02.810 --> 01:48:04.170
Das ist

01:48:04.170 --> 01:48:05.310
wie Heroku, nur cooler.

01:48:07.050 --> 01:48:07.850
Der zweite

01:48:07.850 --> 01:48:09.630
wäre Fly.io. Das ist

01:48:09.630 --> 01:48:10.150
quasi

01:48:10.150 --> 01:48:13.670
Docker-Sachen auf Hosted-Infrastruktur

01:48:13.670 --> 01:48:14.190
überall hin

01:48:14.190 --> 01:48:17.650
machen und die machen krasses technisches Zeugs damit.

01:48:17.830 --> 01:48:19.630
Also du schickst dir den Docker-Container,

01:48:19.730 --> 01:48:21.850
aber die zerlegen den und

01:48:21.850 --> 01:48:23.630
bauen sich da eigene

01:48:23.630 --> 01:48:25.770
Sachen draus. Das ist auch technologisch

01:48:25.770 --> 01:48:26.290
sehr interessant.

01:48:27.410 --> 01:48:29.710
Das war jetzt aber der opportunistische Pick,

01:48:30.310 --> 01:48:31.890
nur um da die

01:48:31.890 --> 01:48:33.790
Alternativen zu Heroku

01:48:33.790 --> 01:48:35.710
und Self-Hosted

01:48:35.710 --> 01:48:36.330
einmal gesagt zu haben.

01:48:36.330 --> 01:48:38.410
Jetzt sind wir ganz tief in den Pop-Bretchen.

01:48:39.470 --> 01:48:41.750
Genau, mein eigentlicher Pick ist was ganz

01:48:41.750 --> 01:48:43.210
anderes und zwar

01:48:43.210 --> 01:48:45.630
das ZDF hat ja

01:48:45.630 --> 01:48:48.010
eine Mediathek und auf dieser Mediathek

01:48:48.010 --> 01:48:49.550
kann man Sachen ansehen und wenn man ein paar Sachen

01:48:49.550 --> 01:48:51.350
angesehen hat, dann versucht das ZDF da

01:48:51.350 --> 01:48:53.550
Recommendations draus

01:48:53.550 --> 01:48:55.370
zu machen. Wow, das ist das

01:48:55.370 --> 01:48:57.790
erste Mal seit Ewigkeiten,

01:48:57.950 --> 01:48:59.610
dass ich von Fernsehen etwas höre.

01:48:59.830 --> 01:49:01.430
Du meinst das ZDF, meinst du das tatsächliche

01:49:01.430 --> 01:49:02.190
Fernsehen? Ja.

01:49:04.270 --> 01:49:05.030
So analog.

01:49:05.390 --> 01:49:07.070
Das zweite deutsche Fernsehen, meine ich.

01:49:08.710 --> 01:49:09.650
Und die,

01:49:09.650 --> 01:49:11.130
also nur die Mediathek.

01:49:12.510 --> 01:49:13.730
Und weil das

01:49:13.730 --> 01:49:15.650
ZDF ja in öffentlich-rechtlicher Hand

01:49:15.650 --> 01:49:17.550
ist, haben die sich gesagt, eigentlich müssen wir das ja

01:49:17.550 --> 01:49:19.390
den Leuten zurückgeben. Und das haben sie tatsächlich gemacht.

01:49:19.490 --> 01:49:20.750
Die haben ihr Recommendation-System

01:49:20.750 --> 01:49:23.570
auf GitHub gepackt.

01:49:23.830 --> 01:49:24.730
Und man kann das jetzt ansehen.

01:49:25.870 --> 01:49:27.710
GitHub ZDF minus Open Source

01:49:27.710 --> 01:49:29.850
gibt es auch jetzt schon

01:49:29.850 --> 01:49:31.370
ein Repository drunter, das heißt

01:49:31.370 --> 01:49:32.830
Recommendations PA Base.

01:49:34.490 --> 01:49:35.190
Und da sind,

01:49:35.770 --> 01:49:37.510
da ist das Recommendations System

01:49:37.510 --> 01:49:39.170
vom ZDF drin. Und fand ich einfach spannend,

01:49:40.010 --> 01:49:41.650
das mal anzusehen.

01:49:41.650 --> 01:49:43.550
Weil da ja doch auch einiges

01:49:43.550 --> 01:49:45.610
an Arbeit drinsteckt. Und weil es da auch

01:49:45.610 --> 01:49:47.290
viele Firmen gibt, die sowas gerne hätten.

01:49:50.750 --> 01:49:54.610
Genau, das war's von mir. Stefan, hast du noch was für uns dabei?

01:49:54.610 --> 01:50:10.070
Ich habe noch etwas herausgefunden. Das ist schon ein älterer Artikel von Bob Nystrom aus dem Jahre 2015. Heißt What Color is Your Function? Und Bob Nystrom ist einer der Sprachdesigner, der jetzt aktuell an Dart arbeitet.

01:50:10.810 --> 01:50:32.170
Und das ist sehr spannend, weil er versucht zu erklären, anhand von Farben, wie sich normale Funktionen und asynchrone Funktionen im Sprachdesign unterscheiden. Also rein aus der Perspektive von, welche Herausforderungen kriegst du als Sprachdesigner, wenn du so ein Asian-Greed-Konstrukt gestalten musst.

01:50:32.970 --> 01:50:34.930
Und wie gesagt, der ist schon ewig alt, aber er ist

01:50:34.930 --> 01:50:37.010
vor kurzem wieder bei uns in der

01:50:37.010 --> 01:50:38.990
Firma aufgepuppt. Kann ich sehr empfehlen.

01:50:40.010 --> 01:50:41.050
Versuch das so zu erklären,

01:50:41.170 --> 01:50:42.570
dass du das, die

01:50:42.570 --> 01:50:43.490
Ergebnisse

01:50:43.490 --> 01:50:47.030
oder die Erkenntnisse in Python

01:50:47.030 --> 01:50:48.130
genauso anwenden kannst.

01:50:49.090 --> 01:50:50.850
Und finde ich immer wieder sehr

01:50:50.850 --> 01:50:51.950
interessant. Gehe sehr oft

01:50:51.950 --> 01:50:53.450
wieder drauf zu.

01:50:54.550 --> 01:50:56.570
Für die Programmiersprachen Interessierten.

01:50:57.170 --> 01:50:58.830
Ja, sehr cool.

01:50:58.830 --> 01:51:00.650
Also quasi diese Analogie

01:51:00.650 --> 01:51:02.190
oder diese Metapher habe ich auch schon häufig gehört.

01:51:02.490 --> 01:51:03.530
Ich wusste aber nicht, wo sie herkommt.

01:51:03.790 --> 01:51:05.450
Und ja, das muss ich auch irgendwo mal lesen.

01:51:05.530 --> 01:51:07.070
Nee, da gibt es tatsächlich noch was Älteres.

01:51:07.190 --> 01:51:08.170
What Color Are Your Bits?

01:51:08.730 --> 01:51:10.990
Das ist von 2004.

01:51:11.830 --> 01:51:15.130
Da geht es um die Herkunft von Bits.

01:51:15.330 --> 01:51:18.530
Also ob deine Bits urheberrechtlich geschützt sind oder nicht.

01:51:19.410 --> 01:51:19.810
Okay.

01:51:20.350 --> 01:51:21.990
Was du damit machen kannst, um die Farbe,

01:51:22.050 --> 01:51:22.950
damit sie die Farbe ändern.

01:51:23.370 --> 01:51:24.590
Aber das ist, ja.

01:51:24.690 --> 01:51:26.190
Also ich musste da auch zuerst dran denken.

01:51:26.410 --> 01:51:27.950
Also es scheint eine gute Metapher zu sein.

01:51:28.470 --> 01:51:29.570
Wir können das ja beides verlinken.

01:51:29.950 --> 01:51:30.910
Ja, sehr gerne.

01:51:32.030 --> 01:51:33.270
Ja. Ja, vielen Dank.

01:51:33.710 --> 01:51:35.870
Ich würde sagen, herzlichen Dank, dass ihr heute

01:51:35.870 --> 01:51:37.970
alle wieder da wart. Herzlichen Dank, Stefan.

01:51:38.090 --> 01:51:39.810
Herzlichen Dank, Johannes. Ja, danke für die Einladung.

01:51:40.330 --> 01:51:41.190
Freut mich sehr. Ja, sehr gern.

01:51:41.670 --> 01:51:43.690
Dann, ja, bleibt uns gewogen.

01:51:43.790 --> 01:51:45.890
Schaltet uns wieder ein. Hört uns, wo immer ihr gerade seid.

01:51:45.990 --> 01:51:47.110
Morgens, mittags, nachts, abends.

01:51:47.650 --> 01:51:49.290
Zum Schlafen, zum Einschlafen.

01:51:50.730 --> 01:51:52.070
Einen wunderschönen Tag.

01:51:52.910 --> 01:51:53.350
Bis bald.

01:51:54.010 --> 01:51:55.910
Tschüss. Ciao. Tschüss.
