WEBVTT

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

00:00:04.000 --> 00:00:07.000
Wir reden heute über Types, Type-Ins und Type-Script.

00:00:08.000 --> 00:00:08.000
Hallo.

00:00:08.000 --> 00:00:10.000
Hallo, willkommen Dominik und...

00:00:10.000 --> 00:00:11.000
Hallo Johannes.

00:00:12.000 --> 00:00:13.000
Hallo zusammen.

00:00:13.000 --> 00:00:14.000
Und hallo Stefan.

00:00:14.000 --> 00:00:15.000
Genau.

00:00:15.000 --> 00:00:16.000
Ja, hallo Stefan.

00:00:16.000 --> 00:00:17.000
Auch ein Gast heute.

00:00:17.000 --> 00:00:18.000
Genau.

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

00:00:24.000 --> 00:00:25.000
Ja, würde ich schon sagen.

00:00:25.000 --> 00:00:26.000
Was gab es denn Schönes?

00:00:27.000 --> 00:00:28.000
Wer möchte anfangen, soll ich?

00:00:28.000 --> 00:00:29.000
Ja, fang du mal an.

00:00:29.000 --> 00:00:31.000
na gut, ja, also

00:00:31.000 --> 00:00:33.000
ehrlich gesagt, das letzte Mal war nicht so lange her, daher

00:00:33.000 --> 00:00:35.000
habe ich ja nicht so viel gesammelt. Heißt ein 3.12.1

00:00:35.000 --> 00:00:37.000
Genau, das ist natürlich irgendwie

00:00:37.000 --> 00:00:39.000
stand irgendwie dabei, so 400 Bugfixes

00:00:39.000 --> 00:00:41.000
und so, also ja, sollte man wahrscheinlich mal

00:00:41.000 --> 00:00:43.000
installieren und meine Frage dazu wäre halt

00:00:43.000 --> 00:00:45.000
bist du jetzt schon umgestiegen

00:00:45.000 --> 00:00:47.000
auf 3.12, weil du wolltest ja immer nur

00:00:47.000 --> 00:00:49.000
die erste meiner Version abwarten, aber dann

00:00:49.000 --> 00:00:51.000
auch, ja? Ja, also noch

00:00:51.000 --> 00:00:53.000
nicht mit allen Sachen, aber mit vielen Sachen

00:00:53.000 --> 00:00:55.000
Okay, sehr gut. Also 3.12.1

00:00:55.000 --> 00:00:57.000
ist draufgekommen und jetzt in meinem

00:00:57.000 --> 00:00:59.000
Systeminterpreter zum Beispiel, ist der auf 3.12.

00:01:00.000 --> 00:01:01.000
Hervorragend.

00:01:01.000 --> 00:01:02.000
Ja, aber ich glaube,

00:01:04.000 --> 00:01:05.000
da war nichts, also außer Bugs

00:01:05.000 --> 00:01:07.000
ist da nichts irgendwie passiert.

00:01:07.000 --> 00:01:09.000
Mein Hauptproblem im Moment ist halt PyTorch oder so was,

00:01:09.000 --> 00:01:11.000
wo es auch im Dezember einen Release gab,

00:01:11.000 --> 00:01:12.000
dass es jetzt endlich mit 3.11 funktioniert.

00:01:13.000 --> 00:01:13.000
Ah, ja, ja.

00:01:13.000 --> 00:01:15.000
Ja, aber...

00:01:15.000 --> 00:01:17.000
Ja, ansonsten genau neue Releases.

00:01:18.000 --> 00:01:19.000
Es gab einen neuen

00:01:19.000 --> 00:01:21.000
Ruby on Rails Release.

00:01:21.000 --> 00:01:23.000
Ich gucke da ab und zu mal so rüber, weil ich halt

00:01:23.000 --> 00:01:24.000
interessant finde, wie viel

00:01:24.000 --> 00:01:27.000
tolles Zeug da passiert.

00:01:27.000 --> 00:01:30.000
Und das ist jetzt deutlich schneller geworden,

00:01:30.000 --> 00:01:33.000
hat irgendwie einen eingebauten Dustin-Time-Compiler

00:01:33.000 --> 00:01:37.000
und verwendet jetzt einen ähnlichen Ansatz für den Parser,

00:01:38.000 --> 00:01:38.000
wie Python halt auch.

00:01:39.000 --> 00:01:42.000
Python ist ja jetzt mit irgendwie 3.9 auf dem Pack-Parser umgestiegen.

00:01:43.000 --> 00:01:47.000
Und das ist, Ruby verwendet da jetzt was ganz Ähnliches.

00:01:47.000 --> 00:01:50.000
Ist auch so ein rekursives Dings da, Parsen.

00:01:50.000 --> 00:01:51.000
Ich weiß nicht, ich habe es wieder vergessen,

00:01:51.000 --> 00:01:52.000
wie das genau heißt.

00:01:53.000 --> 00:01:53.000
So ähnlich.

00:01:53.000 --> 00:01:55.000
Und sie sind auch umgestiegen von Bison,

00:01:55.000 --> 00:01:56.000
also dem Parser-Generator, auf einen anderen.

00:01:56.000 --> 00:02:00.000
Ich habe, finde ich, schon ganz oft Lob für Ruby gehört, muss ich ehrlich sagen.

00:02:00.000 --> 00:02:04.000
Ja, und auch bei dieser ganzen Just-in-Time-Compile-Geschichte,

00:02:04.000 --> 00:02:07.000
da ist, glaube ich, einer der Hauptsponsoren auch Shopify.

00:02:09.000 --> 00:02:09.000
Ja, genau.

00:02:10.000 --> 00:02:12.000
Also es gibt ja viele große Unternehmen,

00:02:12.000 --> 00:02:16.000
die hauptsächlich auf Ruby und Rails Moduliten basieren.

00:02:16.000 --> 00:02:19.000
Und da kommt halt auch eine Menge Geld rein.

00:02:20.000 --> 00:02:25.000
Und ja, Python ist ja jetzt auch dran mit diesem Just-in-Time-Compiler-Thema.

00:02:25.000 --> 00:02:28.000
Das wäre meine News gewesen, Jochen.

00:02:28.000 --> 00:02:28.000
Ach so, sorry.

00:02:29.000 --> 00:02:30.000
Dann schieb's mal los.

00:02:31.000 --> 00:02:34.000
Ja, Ende Dezember

00:02:34.000 --> 00:02:36.000
ist wohl ein Patch in den 3.13

00:02:36.000 --> 00:02:38.000
Branch reingekommen, wo ein JIT-Compiler

00:02:38.000 --> 00:02:40.000
drin ist für Python. Also es ist jetzt

00:02:40.000 --> 00:02:41.000
richtig im Plan drin, dass

00:02:41.000 --> 00:02:43.000
Python in 3.13 einen JIT-Compiler hat.

00:02:43.000 --> 00:02:46.000
Einen Copy-and-Patch-JIT-Compiler.

00:02:46.000 --> 00:02:48.000
Was auch immer das bedeuten mag.

00:02:48.000 --> 00:02:50.000
Da gab's auch angeblich eine wundervolle Diskussion

00:02:50.000 --> 00:02:51.000
auf Reddit zu...

00:02:51.000 --> 00:02:54.000
Ja, also

00:02:54.000 --> 00:02:56.000
es gibt einmal die, ich kann empfehlen,

00:02:56.000 --> 00:02:58.000
es gibt Core-PY, das ist so ein Podcast,

00:02:58.000 --> 00:03:00.000
wo zwei der Core-Entwickler

00:03:00.000 --> 00:03:02.000
irgendwie drüber reden. Da gibt es eine Episode

00:03:02.000 --> 00:03:03.000
zum Just-In-Time-Compiler.

00:03:05.000 --> 00:03:06.000
Wer sind dabei?

00:03:06.000 --> 00:03:07.000
Shannon und Sean? Oder wie ist das?

00:03:08.000 --> 00:03:10.000
Ne, das sind

00:03:10.000 --> 00:03:12.000
Pablo Galindo Salgado,

00:03:13.000 --> 00:03:14.000
der Release-Manager

00:03:14.000 --> 00:03:16.000
auch für 3.13

00:03:16.000 --> 00:03:18.000
und

00:03:18.000 --> 00:03:19.000
Luca Schlanger.

00:03:20.000 --> 00:03:21.000
Ah ja. Genau.

00:03:22.000 --> 00:03:24.000
Die haben da einmal drüber geredet und

00:03:24.000 --> 00:03:26.000
daher weiß ich auch, dass das

00:03:26.000 --> 00:03:28.000
basiert hauptsächlich,

00:03:28.000 --> 00:03:30.000
also warum man das jetzt nochmal in Angriff nimmt,

00:03:30.000 --> 00:03:32.000
auf Geschichten, die in Lua

00:03:32.000 --> 00:03:34.000
passiert sind. Da gab es jetzt auch irgendwelche

00:03:34.000 --> 00:03:36.000
– ich habe jetzt wieder die

00:03:36.000 --> 00:03:38.000
Details vergessen – aber so Papers,

00:03:38.000 --> 00:03:40.000
die sehr, sehr interessant aussahen und

00:03:40.000 --> 00:03:42.000
die halt vermuten lassen, dass man es relativ leicht

00:03:42.000 --> 00:03:44.000
irgendwie auch für Python verwenden kann.

00:03:44.000 --> 00:03:45.000
Und ja, das ist halt ein

00:03:45.000 --> 00:03:48.000
InPython in Ruby.

00:03:48.000 --> 00:03:49.000
Da werden überall diese Dinger jetzt gerade eingebaut.

00:03:50.000 --> 00:03:51.000
Und hier der

00:03:51.000 --> 00:03:53.000
wegen dem PyPy auch hier war schon

00:03:53.000 --> 00:03:57.000
der meinte auch so,

00:03:57.000 --> 00:03:58.000
oh, er muss jetzt mal sein

00:03:58.000 --> 00:04:00.000
Commit-Bit

00:04:00.000 --> 00:04:03.000
wieder hochfahren.

00:04:03.000 --> 00:04:05.000
Wieder quasi aus...

00:04:05.000 --> 00:04:07.000
Ja, es gab ja immer, dass die neuen Versionen

00:04:07.000 --> 00:04:09.000
deutlich einfacher zu implementieren sind bei PyPy,

00:04:09.000 --> 00:04:11.000
wenn das drin ist, was da

00:04:11.000 --> 00:04:12.000
in C-Extensions irgendwie dazukommen

00:04:12.000 --> 00:04:15.000
sollte, wollte, wenn ich das richtig verstanden

00:04:15.000 --> 00:04:16.000
hatte damals. Ja, also

00:04:16.000 --> 00:04:18.000
jedenfalls, der macht da jetzt auch mit.

00:04:19.000 --> 00:04:21.000
Ah, cool. Das wird auf jeden Fall spannend.

00:04:22.000 --> 00:04:22.000
Schnelles Python.

00:04:22.000 --> 00:04:52.000
Ja, genau.

00:04:52.000 --> 00:04:54.000
Es gab dann ein Issue zu, wo dann einer

00:04:54.000 --> 00:05:05.000
von Netflix oder so in relativ freundlichem Ton zun schrieb irgendwie so ja also das macht bei uns sehr viel Arbeit und irgendwie das war jetzt alles irgendwie nicht so g und ich hab dann

00:05:05.000 --> 00:05:07.000
geguckt, der hat dann auch irgendwann beschrieben, welche Issues

00:05:07.000 --> 00:05:09.000
die da reingelaufen sind und das war halt zum Beispiel auch

00:05:09.000 --> 00:05:11.000
einer von den Dingern, in die ich

00:05:11.000 --> 00:05:12.000
da reingerannt bin

00:05:12.000 --> 00:05:14.000
und

00:05:14.000 --> 00:05:17.000
ja, genau, der meinte dann

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

00:05:19.000 --> 00:05:21.000
das Paket irgendwie umbenannt hätte oder so

00:05:21.000 --> 00:05:23.000
und das wollten sie aber nicht machen

00:05:23.000 --> 00:05:25.000
Und dann haben sie gesagt, nee, das geht auch so oder geht so.

00:05:25.000 --> 00:05:26.000
Und das ging alles nicht.

00:05:26.000 --> 00:05:27.000
Und das war relativ furchtbar.

00:05:28.000 --> 00:05:30.000
Also gerade wenn man eine Library ist,

00:05:30.000 --> 00:05:31.000
hat man damit halt ein großes Problem,

00:05:31.000 --> 00:05:32.000
weil man nicht kontrollieren kann,

00:05:33.000 --> 00:05:35.000
was in der Applikation, die einen benutzt,

00:05:35.000 --> 00:05:37.000
halt irgendwie für eine Pydentic-Version ist.

00:05:38.000 --> 00:05:40.000
Und zum Beispiel FastAPI hat damit auch ein Riesenproblem gehabt.

00:05:41.000 --> 00:05:43.000
Und wie die das dann letztendlich gemacht haben,

00:05:43.000 --> 00:05:45.000
ist, sie haben halt so einen Flag eingeführt, Pydentic V2,

00:05:46.000 --> 00:05:49.000
und machen dann jetzt gerade so was wie if Pydentic V2.

00:05:49.000 --> 00:05:50.000
Bäh.

00:05:50.000 --> 00:05:52.000
500 Zeilen eingerückt,

00:05:52.000 --> 00:05:54.000
irgendwie Kompatibilitätsleer

00:05:54.000 --> 00:05:56.000
und dann Else und dann sonst.

00:05:56.000 --> 00:05:57.000
Und das haben sie an mehreren Stellen.

00:05:57.000 --> 00:05:59.000
Das ist wirklich absolut schrecklich.

00:05:59.000 --> 00:06:01.000
Naja, aber so sieht es halt aus.

00:06:01.000 --> 00:06:03.000
Dieses Update war nicht

00:06:03.000 --> 00:06:06.000
wirklich reibungslos,

00:06:06.000 --> 00:06:08.000
sondern da haben viele Leute irgendwie eine Menge

00:06:08.000 --> 00:06:10.000
Schweiß gelassen.

00:06:10.000 --> 00:06:11.000
Also nicht nur ich.

00:06:12.000 --> 00:06:14.000
Okay, also gut, wenn man es nicht zu sehr

00:06:14.000 --> 00:06:15.000
drin hat. Ich habe tatsächlich auch

00:06:15.000 --> 00:06:18.000
zwischendurch noch auf eins dependen müssen,

00:06:18.000 --> 00:06:19.000
weil da so bei zwei Sachen nicht so ging,

00:06:19.000 --> 00:06:21.000
was jetzt irgendwie geht, aber ja.

00:06:22.000 --> 00:06:23.000
Ein bisschen nervig.

00:06:24.000 --> 00:06:25.000
Johannes, hast du noch was?

00:06:26.000 --> 00:06:28.000
Nee, also in der

00:06:28.000 --> 00:06:29.000
TypeScript-Welt gibt es sowas nicht.

00:06:30.000 --> 00:06:32.000
Aber jetzt kann man uns über TypeScript-Versionen

00:06:32.000 --> 00:06:32.000
unterhalten.

00:06:34.000 --> 00:06:35.000
Apropos, ich habe gehört, dass ein neues Buch erschienen

00:06:35.000 --> 00:06:37.000
in der TypeScript-Welt. Echt, was?

00:06:38.000 --> 00:06:39.000
Das ist mir ganz neu.

00:06:39.000 --> 00:06:41.000
Ich glaube, das muss der Stefan mal so ein bisschen erzählen.

00:06:41.000 --> 00:06:43.000
Ist das jetzt mein Intro oder was?

00:06:43.000 --> 00:06:45.000
Ja, das war die Software-Überleitung.

00:06:45.000 --> 00:06:46.000
Ja, genau.

00:06:46.000 --> 00:07:11.000
Ich habe das jetzt total spannend gefunden, weil es wird ja immer so gemunkert, dass im Web-Bereich gibt es ja quasi alle drei Minuten irgendeinen neuen Fachbegriff oder irgendeinen neuen Bibliothekennamen oder irgendein neues JavaScript-Framework, das irgendeinen abstrusen Namen hat, mit dem sich alle nachher irgendwie auseinandersetzen müssen.

00:07:11.000 --> 00:07:13.000
und das ist jetzt das zweite Mal,

00:07:14.000 --> 00:07:15.000
dass ich so in diese Python-Ecke reinschaue

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

00:07:19.000 --> 00:07:19.000
Den ersten

00:07:19.000 --> 00:07:21.000
Namen, den ich erkannt habe,

00:07:21.000 --> 00:07:22.000
das war fast API,

00:07:23.000 --> 00:07:25.000
weil tatsächlich, das ist spannend, ich bin

00:07:25.000 --> 00:07:27.000
jetzt mit, seit

00:07:27.000 --> 00:07:29.000
vier, fünf Monaten bei uns in der

00:07:29.000 --> 00:07:31.000
Firma mit einer Gruppe Python-Developern

00:07:31.000 --> 00:07:33.000
unterwegs, Data Scientist, ganz klassisch,

00:07:34.000 --> 00:07:35.000
du hast einen Data Scientist

00:07:35.000 --> 00:07:37.000
und

00:07:37.000 --> 00:07:39.000
das Tool der Wahl ist Python, die Bibliotheken sind da,

00:07:39.000 --> 00:07:42.000
das übliche mit Longchain, Pipa Pro

00:07:42.000 --> 00:07:44.000
für diese ganze LLM

00:07:44.000 --> 00:07:46.000
Sache. Und das war so

00:07:46.000 --> 00:07:48.000
mein erstes

00:07:48.000 --> 00:07:50.000
Intro in dieser Python-Welt und ich bin schon

00:07:50.000 --> 00:07:52.000
massiv gescheitert daran, dass ich den Package-Manager

00:07:52.000 --> 00:07:53.000
auswähle,

00:07:54.000 --> 00:07:55.000
der passt. Da gibt es ja dann

00:07:55.000 --> 00:07:57.000
Conda, Anaconda,

00:07:58.000 --> 00:08:00.000
Pep oder sind das ganz andere?

00:08:00.000 --> 00:08:02.000
Keine Ahnung. Also wie gesagt, das ist ja schon wieder

00:08:02.000 --> 00:08:04.000
vorbei. Aber ich

00:08:04.000 --> 00:08:06.000
weiß, dass ich fast immer noch langen, langen

00:08:06.000 --> 00:08:07.000
Gesprächen mit unseren Python-Devs

00:08:07.000 --> 00:08:10.000
in unser Architektur-Diagramm eingetragen

00:08:10.000 --> 00:08:12.000
habe für irgendeinen Server, den wir

00:08:12.000 --> 00:08:14.000
gemacht haben. Genau, also das war eben das

00:08:14.000 --> 00:08:16.000
Erste, wo ich mir gedacht habe, so, da kenne ich mich

00:08:16.000 --> 00:08:18.000
jetzt aus, bei FastAPI, da kann ich mitreden.

00:08:20.000 --> 00:08:20.000
Funktioniert

00:08:20.000 --> 00:08:22.000
Multithreaded, aber

00:08:22.000 --> 00:08:24.000
nicht Async. Ist das richtig?

00:08:25.000 --> 00:08:26.000
Nee, also kann

00:08:26.000 --> 00:08:28.000
man wahrscheinlich so betreiben, wenn man wirklich will,

00:08:28.000 --> 00:08:29.000
aber nee, es ist tatsächlich Async.

00:08:30.000 --> 00:08:31.000
Also unter FastAPI liegt

00:08:31.000 --> 00:08:34.000
normalerweise, so würde ich jetzt mal

00:08:34.000 --> 00:08:36.000
sagen, wenn man das so betreibt, wie es gedacht

00:08:36.000 --> 00:08:37.000
ist halt

00:08:37.000 --> 00:08:40.000
Stalett beziehungsweise UV-Corn

00:08:40.000 --> 00:08:42.000
und das ist halt sozusagen die

00:08:42.000 --> 00:08:44.000
LibUV, also das ist halt

00:08:44.000 --> 00:08:46.000
eine Adaption von LinnUV, was halt auch

00:08:46.000 --> 00:08:48.000
unter der Event-Loop bei Node.js

00:08:48.000 --> 00:08:50.000
liegt halt für Python.

00:08:51.000 --> 00:08:52.000
Ja, und

00:08:52.000 --> 00:08:54.000
also ist halt quasi genauso schnell

00:08:54.000 --> 00:08:55.000
dann auch und ist Async.

00:08:56.000 --> 00:08:58.000
Cool. Das war die

00:08:58.000 --> 00:09:00.000
zweite, war dann, dass ich

00:09:00.000 --> 00:09:01.000
versucht habe,

00:09:02.000 --> 00:09:03.000
über Pyro 3

00:09:03.000 --> 00:09:05.000
eine Brücke zwischen

00:09:05.000 --> 00:09:07.000
zwischen Async Rust und Async Python

00:09:07.000 --> 00:09:08.000
einmal zu schreiben. Das war spannend.

00:09:09.000 --> 00:09:11.000
Das war richtig cool. Also was mich da

00:09:11.000 --> 00:09:13.000
beeindruckt hat, und mit dem habe ich

00:09:13.000 --> 00:09:14.000
nicht gerechnet, ist, dass

00:09:14.000 --> 00:09:17.000
das Foreign-Francish-Interface von Python

00:09:17.000 --> 00:09:19.000
ja fantastisch ist. Also du

00:09:19.000 --> 00:09:21.000
hast dort dein kompiliertes

00:09:21.000 --> 00:09:22.000
SO-Modul dazu und du kannst auf

00:09:22.000 --> 00:09:25.000
die Objektliste zugreifen

00:09:25.000 --> 00:09:26.000
und kannst die Identifier herauslesen.

00:09:27.000 --> 00:09:29.000
Also das Kompilieren vom Rust-Code

00:09:29.000 --> 00:09:30.000
war auf jeden Fall anspruchsvoller,

00:09:31.000 --> 00:09:33.000
als wir nachher die Symbole in

00:09:33.000 --> 00:09:34.000
Python zu loben und zu verwenden. Das war

00:09:34.000 --> 00:09:36.000
richtig, richtig beeindruckend. Also

00:09:36.000 --> 00:09:39.000
coole Sache, möchte ich mir auf jeden Fall

00:09:39.000 --> 00:09:40.000
mehr anschauen. Aber das ist es.

00:09:40.000 --> 00:09:42.000
Das sind meine Python-Kenntnisse.

00:09:43.000 --> 00:09:44.000
Ja, aber ich finde auch,

00:09:44.000 --> 00:09:46.000
das Benutzen von Python ist halt das, was so Spaß

00:09:46.000 --> 00:09:48.000
macht. Also

00:09:48.000 --> 00:09:50.000
High-Level-Interface, ich glaube, ist sehr gut geeignet.

00:09:51.000 --> 00:09:52.000
PS3, auch ein cooles Beispiel.

00:09:52.000 --> 00:10:06.000
Da gibt es die meisten Sachen die es irgendwie kann Ich glaube was es nicht kann ist irgendwie Iteratoren ausspucken richtig oder so oder Generatoren ergeben Ja das wird wahrscheinlich schwierig sein Das kann ich mir gut vorstellen Keine Ahnung Da ist dieses Typsystem von Rust halt doch sehr sehr eigen und

00:10:06.000 --> 00:10:07.000
sehr schwierig in andere

00:10:07.000 --> 00:10:10.000
Sprachen zu integrieren.

00:10:11.000 --> 00:10:12.000
Nehme ich mal an. Ja, aber

00:10:12.000 --> 00:10:14.000
ich hatte ja als News ja auch quasi noch ein bisschen Werbung

00:10:14.000 --> 00:10:16.000
gemacht für dein Buch. Vielleicht willst du dazu noch irgendwie kurz

00:10:16.000 --> 00:10:18.000
was sagen? Ja,

00:10:18.000 --> 00:10:19.000
Dankeschön. Danke für diese Überleitung.

00:10:20.000 --> 00:10:21.000
Ich habe tatsächlich

00:10:21.000 --> 00:10:23.000
in den letzten Jahren

00:10:23.000 --> 00:10:26.000
TypeScript-Bücher geschrieben.

00:10:26.000 --> 00:10:27.000
Das erste Buch, das ich geschrieben habe,

00:10:28.000 --> 00:10:30.000
war in 2020

00:10:30.000 --> 00:10:31.000
TypeScript in 50 Lessons,

00:10:31.000 --> 00:10:34.000
das beim Smashing Magazine Verlag

00:10:34.000 --> 00:10:35.000
rausgekommen ist, das als

00:10:35.000 --> 00:10:38.000
angenehmer,

00:10:38.000 --> 00:10:40.000
unaufgeregter Einstieg

00:10:40.000 --> 00:10:42.000
in TypeScript als Typsystem

00:10:42.000 --> 00:10:43.000
auf JavaScript gedacht ist.

00:10:43.000 --> 00:10:46.000
Das Zielpublikum waren

00:10:46.000 --> 00:10:47.000
Entwicklerinnen und Entwickler, die

00:10:47.000 --> 00:10:50.000
JavaScript schon kennen, sich dort

00:10:50.000 --> 00:10:52.000
auch schon wohlfühlen und jetzt merken

00:10:52.000 --> 00:10:57.000
jetzt müssen sie TypeScript verwenden, brauchen die Info, warum man das erstens überhaupt haben will

00:10:57.000 --> 00:11:01.000
und zweitens, wie das jetzt so richtig funktioniert und warum es da so viel Syntax gibt

00:11:01.000 --> 00:11:07.000
und warum das so kompliziert ausschaut und versucht, das grundlegende System,

00:11:07.000 --> 00:11:12.000
Typsystem runterzubrechen auf einfach zu verdauende Lektionen.

00:11:13.000 --> 00:11:20.000
Genau, das war das Ziel von dem Buch. Das habe ich dann zufälligerweise in 50 Lektionen geschafft.

00:11:20.000 --> 00:11:25.000
Das war ein Riesenspaß. Das war quasi mein Corona-Projekt, mein erstes Lockdown-Projekt.

00:11:25.000 --> 00:11:30.000
Wobei, stimmt nicht, ich habe es zwischen dem ersten und dem zweiten Lockdown tatsächlich das meiste geschrieben.

00:11:30.000 --> 00:11:33.000
Das ist auch tatsächlich ein schickes Buch. Das sieht auch super aus, also von außen.

00:11:34.000 --> 00:11:38.000
Wir wissen das, weil wir dieses Buch auch alle haben.

00:11:38.000 --> 00:11:38.000
Ja, tatsächlich.

00:11:38.000 --> 00:11:40.000
Zwar als Python-Entwickler, was natürlich auch schon was heißt.

00:11:41.000 --> 00:11:44.000
Alles ohne die Kamera gehalten. Das macht mich irrsinnig happy.

00:11:44.000 --> 00:11:48.000
Ihr kennt sich das nicht vorstellen. Das sind diese unglaublich schönen Momente,

00:11:48.000 --> 00:11:53.000
wenn man sieht, dass das Buch tatsächlich an Leute kommt und Leute das verwenden.

00:11:53.000 --> 00:11:55.000
Also die Lesepäntchen gesehen herrlich spitze.

00:11:56.000 --> 00:11:58.000
Und die Optik ist wirklich ganz, ganz besonders,

00:11:58.000 --> 00:12:01.000
weil das war eigentlich auch ein Grund,

00:12:01.000 --> 00:12:03.000
warum ich mit Smashing Magazine zusammenarbeiten wollte.

00:12:03.000 --> 00:12:06.000
Die haben einfach irrsinnig viel Liebe zum Detail

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

00:12:10.000 --> 00:12:12.000
haben eine wunderschöne Typografie, das sauber zu lesen ist

00:12:12.000 --> 00:12:16.000
und verzetteln sie dann in kleinen Finessen so stark.

00:12:16.000 --> 00:12:33.000
Und ich habe zum Beispiel, das Cover wurde gestaltet von Rob Draper, den habe ich tatsächlich in Düsseldorf kennengelernt, auf der Björn Tellerrand, der als Künstler die Intro-Grafiken zu den Golden Globes gemacht hat, für Nike und BMX-Fahrräder bzw. Schuhe designt hat.

00:12:33.000 --> 00:12:35.000
und der mich gefragt hat, hey, so,

00:12:35.000 --> 00:12:37.000
E-Mail geschrieben, hey, der war aber das cool,

00:12:38.000 --> 00:12:40.000
möchtest du mein Buch designen? Ja, passt.

00:12:40.000 --> 00:12:42.000
Und ich habe gedacht, hey, wow, cool, ich hoffe, er kostet jetzt

00:12:42.000 --> 00:12:43.000
nicht eine Million oder so.

00:12:44.000 --> 00:12:45.000
Er hat tatsächlich dann

00:12:45.000 --> 00:12:47.000
das Buch gestaltet,

00:12:49.000 --> 00:12:50.000
also versucht

00:12:50.000 --> 00:12:51.000
er mit diesem Kapitel

00:12:51.000 --> 00:12:53.000
in Lays ein bisschen

00:12:53.000 --> 00:12:56.000
das Ganze zugänglich zu machen,

00:12:56.000 --> 00:12:58.000
freundlich zu machen, das war uns ganz, ganz

00:12:58.000 --> 00:13:00.000
wichtig und die Person,

00:13:00.000 --> 00:13:02.000
die nachher, also die Ari, die nachher das Ganze

00:13:02.000 --> 00:13:07.000
gesetzt hat und versucht hat, ein Produkt daraus zu machen, hat dann auch recherchiert

00:13:07.000 --> 00:13:11.000
und hat zum Beispiel das Lesebändchen, das rote Lesebändchen in der Farbe bestellt von

00:13:11.000 --> 00:13:14.000
den roten Unterlinien in Visual Studio Code.

00:13:14.000 --> 00:13:19.000
Das heißt, das ist der gleiche Farbton und so tief ins Detail geht es dort und das ist

00:13:19.000 --> 00:13:25.000
halt einfach absolut herrlich für mich, der praktisch nur den Text beigetragen hat, dass

00:13:25.000 --> 00:13:31.000
du siehst, wie andere Leute sich so investieren in dieses Projekt und versuchen, gemeinsam

00:13:31.000 --> 00:13:33.000
oder irgendwas Cooles draus zu machen,

00:13:33.000 --> 00:13:34.000
da kriege ich heute noch Gänsehaut.

00:13:35.000 --> 00:13:35.000
Das ist ja für mich so,

00:13:36.000 --> 00:13:37.000
ich weiß, es ist mein Buch,

00:13:38.000 --> 00:13:39.000
aber es ist nicht nur mein Buch.

00:13:39.000 --> 00:13:41.000
Da sind so viele Leute daran beteiligt gewesen.

00:13:41.000 --> 00:13:43.000
Es war ein irrsinnig cooler Effort

00:13:43.000 --> 00:13:44.000
von so vielen Menschen

00:13:44.000 --> 00:13:46.000
und das macht mich einfach jedes Mal wieder glücklich,

00:13:46.000 --> 00:13:47.000
wenn ich dann sehe,

00:13:47.000 --> 00:13:49.000
dass das Leute auch so sehen,

00:13:50.000 --> 00:13:51.000
sie das in die Bücherregale stellen

00:13:51.000 --> 00:13:53.000
oder das Beste, was du machen kannst,

00:13:54.000 --> 00:13:55.000
hast du einen Zoom-Call,

00:13:55.000 --> 00:13:56.000
stell es in den Hintergrund

00:13:56.000 --> 00:13:57.000
und schick mir ein Foto von dem Zoom-Call.

00:13:57.000 --> 00:13:58.000
Das ist das Allerbeste.

00:13:58.000 --> 00:13:59.000
Das macht mir die größte, größte Freude.

00:13:59.000 --> 00:14:02.000
und es hat eine Freude für mich gemacht,

00:14:02.000 --> 00:14:04.000
wie er ein Interview

00:14:04.000 --> 00:14:06.000
für sein Startup gemacht hat,

00:14:06.000 --> 00:14:07.000
auf einmal sehe ich, hey, da ist mein Buch im Hintergrund,

00:14:08.000 --> 00:14:10.000
herrlich, also macht

00:14:10.000 --> 00:14:10.000
Riesenspaß.

00:14:11.000 --> 00:14:14.000
Das war das erste TypeScript-Buch, ich habe dann noch ein zweites

00:14:14.000 --> 00:14:15.000
TypeScript-Buch geschrieben, das ist erst

00:14:15.000 --> 00:14:17.000
im September rausgekommen, also ist noch ganz, ganz frisch,

00:14:18.000 --> 00:14:20.000
das ist das TypeScript-Cookbook,

00:14:20.000 --> 00:14:21.000
das jetzt mit O'Reilly

00:14:21.000 --> 00:14:22.000
veröffentlicht worden ist,

00:14:24.000 --> 00:14:25.000
das war praktisch

00:14:25.000 --> 00:14:27.000
eine Auftragsarbeit, also O'Reilly hat

00:14:27.000 --> 00:14:31.000
zu diesen Acquisition-Editors, die suchen halt noch potenziellen Autoren,

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

00:14:35.000 --> 00:14:39.000
Und sie haben gesagt, sie wollen ein TypeScript-Buch veröffentlichen in diesem Stil

00:14:39.000 --> 00:14:43.000
wie TypeScript in 50 Lessons, ob ich mir vorstellen kann, noch ein solches zu schreiben.

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

00:14:46.000 --> 00:14:51.000
ich habe halt einfach eine gewisse Ansicht, eine gewisse Stimme,

00:14:51.000 --> 00:15:05.000
eine gewisse Idee zu dem Ganzen habe aber gedacht naja wenn du sie so reil probierst oder mal kurz ein Inhaltsverzeichnis unterschreibst wie du dir ein zweites Buch vorstellen kannst Und gerade habe ich 100 weitere Eintr gehabt innerhalb von drei Stunden

00:15:05.000 --> 00:15:07.000
Also ich bin mir am Nachmittag hingesetzt und habe gedacht,

00:15:07.000 --> 00:15:08.000
ups, wow, da ist ein Buch da.

00:15:10.000 --> 00:15:11.000
Und bin mit denen in einen Vertrag gegangen

00:15:11.000 --> 00:15:12.000
und habe dann versucht,

00:15:12.000 --> 00:15:16.000
den Nachfolger vom TypeScript in 50 Lessons Buch zu schreiben.

00:15:16.000 --> 00:15:18.000
Wenn du in TypeScript in 50 Lessons lernst,

00:15:19.000 --> 00:15:20.000
wie das Typ-System funktioniert,

00:15:20.000 --> 00:15:22.000
lernst du im TypeScript-Book alle Dinge,

00:15:22.000 --> 00:15:23.000
die schief gehen können.

00:15:23.000 --> 00:15:26.000
Dinge, die, wenn du wirklich Programme damit schreibst,

00:15:26.000 --> 00:15:28.000
wo du merkst, hey, da passt gerade was nicht,

00:15:28.000 --> 00:15:30.000
da spielt das Typsystem nicht so mit,

00:15:30.000 --> 00:15:32.000
wie ich mir das denke, beziehungsweise

00:15:32.000 --> 00:15:34.000
brauche ich halt irgendeine Technik oder irgendein

00:15:34.000 --> 00:15:36.000
Prinzip oder irgendein

00:15:36.000 --> 00:15:37.000
Pattern, das ich anwenden kann,

00:15:38.000 --> 00:15:39.000
um einem gewissen Problem entgegenzukommen.

00:15:39.000 --> 00:15:42.000
Im Moment, ich dachte, so Typen hast du damit,

00:15:42.000 --> 00:15:43.000
nichts mehr schiefgehen kann. Und mit

00:15:43.000 --> 00:15:46.000
sicheren statischen Typen sind die

00:15:46.000 --> 00:15:47.000
Sprachen immer ganz besonders gut.

00:15:48.000 --> 00:15:50.000
Genau, da beschreibt man nur mehr Programme, die

00:15:50.000 --> 00:15:52.000
nur mehr funktionieren und man hat keine Bugs

00:15:52.000 --> 00:15:53.000
mehr und es ist super happy.

00:15:54.000 --> 00:15:54.000
Ja, genau.

00:15:56.000 --> 00:15:58.000
Ich bin eine super Überleitung

00:15:58.000 --> 00:16:00.000
tatsächlich auf das Thema, was wir heute machen wollen, oder?

00:16:01.000 --> 00:16:01.000
Ja.

00:16:04.000 --> 00:16:05.000
Ganz herzlichen Dank, dass du heute da bist, Stefan.

00:16:05.000 --> 00:16:06.000
Das freut uns sehr.

00:16:07.000 --> 00:16:09.000
In Paisen haben wir von Typen auch schon das eine,

00:16:09.000 --> 00:16:11.000
andere Mal am Rande gehört.

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

00:16:13.000 --> 00:16:15.000
weil wir uns nie ausreichend vorbereitet gefühlt haben.

00:16:16.000 --> 00:16:17.000
Weil es halt so ein großes Thema ist.

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

00:16:19.000 --> 00:16:20.000
in Paisen für Types.

00:16:20.000 --> 00:16:22.000
irgendwie. Ja, es gibt auch viele,

00:16:22.000 --> 00:16:23.000
die das nicht so mögen, ja.

00:16:24.000 --> 00:16:26.000
Wie seid ihr da so drauf?

00:16:27.000 --> 00:16:28.000
Also habt ihr jetzt Typen schon

00:16:28.000 --> 00:16:30.000
in eurem Python-Code drinnen oder ist das eher noch so

00:16:30.000 --> 00:16:32.000
das Buch mit sieben Siegeln, das ihr nicht

00:16:32.000 --> 00:16:34.000
öffnen wollt? Annotationen nutze

00:16:34.000 --> 00:16:36.000
ich persönlich sehr gerne, insbesondere dann, wenn

00:16:36.000 --> 00:16:38.000
ich mit anderen Menschen arbeite, um einfach

00:16:38.000 --> 00:16:40.000
so zu dokumentieren, was macht das denn

00:16:40.000 --> 00:16:42.000
überhaupt. Das heißt aber nicht,

00:16:42.000 --> 00:16:43.000
dass das immer stimmt, was da steht.

00:16:47.000 --> 00:16:48.000
Das ist aber gefährlich.

00:16:48.000 --> 00:16:50.000
Ja, das ist ein gefährliches Spiel.

00:16:50.000 --> 00:17:03.000
Ja, also ich verwende sie auch schon und ich habe halt ein Projekt mal so komplett irgendwie annotiert, einfach nur auch, weil ich wissen wollte, wie schwierig ist es denn nun, wie weh tut es denn irgendwie.

00:17:03.000 --> 00:17:07.000
und ja, das ging schon,

00:17:07.000 --> 00:17:09.000
aber es war auch, also ich habe

00:17:09.000 --> 00:17:11.000
da jetzt nicht so wahnsinnig viel

00:17:11.000 --> 00:17:12.000
irgendwie

00:17:12.000 --> 00:17:15.000
Nutzen rausziehen können, aber

00:17:15.000 --> 00:17:17.000
ich hatte auch vorher neben dem Ding halt auch schon

00:17:17.000 --> 00:17:19.000
100% Test-Coverage, insofern

00:17:19.000 --> 00:17:21.000
war da einfach wahrscheinlich nicht mehr so viel

00:17:21.000 --> 00:17:22.000
zu,

00:17:23.000 --> 00:17:24.000
ja auch das habe ich

00:17:24.000 --> 00:17:26.000
ja gemacht, um es mal gemacht zu haben,

00:17:26.000 --> 00:17:27.000
als das halt wirklich Nutzen hatte.

00:17:27.000 --> 00:17:30.000
Ich habe tatsächlich in den Projekten bei mir jetzt Enforced MyPy

00:17:30.000 --> 00:17:32.000
Pre-Commit-Hook, das ist auch

00:17:32.000 --> 00:17:34.000
schon, da gehe ich ziemlich vielen Leuten auf die Nerven.

00:17:35.000 --> 00:17:35.000
Aber...

00:17:35.000 --> 00:17:38.000
Da kannst du überall Objekt hinschreiben, oder? Das zählt doch auch.

00:17:38.000 --> 00:17:40.000
Ja, okay. Also da sind die

00:17:40.000 --> 00:17:41.000
meisten nicht draufgekommen.

00:17:42.000 --> 00:17:44.000
Oh, da habe ich jetzt ein Geheimnis verraten.

00:17:44.000 --> 00:17:44.000
Hups.

00:17:46.000 --> 00:17:46.000
Annie oder Anna.

00:17:47.000 --> 00:17:50.000
Also ich bin

00:17:50.000 --> 00:17:52.000
beeindruckt von der 100% Test Courage.

00:17:52.000 --> 00:17:53.000
Also ich bin

00:17:53.000 --> 00:17:56.000
leider Gottes der faulste Tester.

00:17:57.000 --> 00:17:58.000
Dieseits der Donau.

00:17:58.000 --> 00:18:00.000
Also das ist...

00:18:00.000 --> 00:18:01.000
Ich sage immer, also ich habe

00:18:01.000 --> 00:18:04.000
diesen Spruch gehabt, wie ich noch in einer

00:18:04.000 --> 00:18:06.000
Agentur gearbeitet habe, dass ich sage, ja, getestet wird beim

00:18:06.000 --> 00:18:07.000
Kunden, wenn es in Production ist,

00:18:07.000 --> 00:18:09.000
es soll reichen, aber

00:18:09.000 --> 00:18:12.000
ich, keine Ahnung,

00:18:12.000 --> 00:18:14.000
liegt es an der Software,

00:18:14.000 --> 00:18:15.000
die ich schreibe oder an der Rolle, in der ich bin,

00:18:16.000 --> 00:18:18.000
ich bin sehr, sehr selten

00:18:18.000 --> 00:18:20.000
jemand, der wirklich ausgiebige

00:18:20.000 --> 00:18:21.000
Testsuit schreibt und da,

00:18:22.000 --> 00:18:24.000
also das ist, glaube ich,

00:18:24.000 --> 00:18:26.000
also auch schärfenhaupt, das ist, glaube ich,

00:18:26.000 --> 00:18:27.000
meine größte Schwäche.

00:18:27.000 --> 00:18:30.000
Ja, 100% Courage ist auch schon sehr

00:18:30.000 --> 00:18:33.000
ich finde es beeindruckend, wirklich.

00:18:33.000 --> 00:18:35.000
Ja, das haben wir in dem Projekt, in dem ich bin, auch 100%

00:18:35.000 --> 00:18:37.000
Branch Coverage sogar.

00:18:38.000 --> 00:18:39.000
Und TypeScript.

00:18:39.000 --> 00:18:42.000
Es ist ja oft so, dass man das so ein bisschen

00:18:42.000 --> 00:18:43.000
als gegensätzliche

00:18:43.000 --> 00:18:45.000
Pole ansieht, sag ich mal. Die einen machen

00:18:45.000 --> 00:18:47.000
Typen und die anderen machen Testing.

00:18:47.000 --> 00:18:50.000
Und das ist schön, Stefan, dass du das jetzt bestätigt hast,

00:18:50.000 --> 00:18:50.000
aber

00:18:50.000 --> 00:18:54.000
Ich bin quasi das Typen

00:18:54.000 --> 00:18:55.000
Paradebeispiel.

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

00:18:57.000 --> 00:18:59.000
JavaScript und Python haben ja

00:18:59.000 --> 00:19:01.000
die gleiche Eigenschaft, dass beides

00:19:01.000 --> 00:19:03.000
in der Praxis dynamisch

00:19:03.000 --> 00:19:05.000
typisierte Sprachen sind.

00:19:05.000 --> 00:19:07.000
Sprich, natürlich gibt es Typen, sonst könntest du mit den ganzen

00:19:07.000 --> 00:19:09.000
Werten nichts anfangen. Es ist aber relativ

00:19:09.000 --> 00:19:11.000
egal, was das für ein ist. Du kannst dann

00:19:11.000 --> 00:19:13.000
ein Number oder ein Integer

00:19:13.000 --> 00:19:15.000
einer Variable zuweisen und im nächsten

00:19:15.000 --> 00:19:17.000
Schritt dann String und keiner regt sie auf

00:19:17.000 --> 00:19:19.000
und keiner beschwert sie und es funktioniert halt einfach.

00:19:20.000 --> 00:19:21.000
Oder du kannst verschiedene Typen mischen.

00:19:21.000 --> 00:19:23.000
Du kannst ein String mit einer Zahl kombinieren.

00:19:23.000 --> 00:19:24.000
Nein, das geht in Pandas.

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

00:19:27.000 --> 00:19:28.000
als in JavaScript.

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

00:19:31.000 --> 00:19:33.000
Dass du solche implizite Konversionen drin hast.

00:19:34.000 --> 00:19:38.000
Ja, also das heißt ja immer weak getyped versus strong getyped,

00:19:38.000 --> 00:19:40.000
aber ich weiß nicht, ob das irgendein Sinn ergibt.

00:19:40.000 --> 00:19:43.000
Ja, dynamic versus static, aber diese ganzen Bezeichnungen sind ja alle nur so ein bisschen.

00:19:44.000 --> 00:19:47.000
Also die schöneren Bezeichnungen sind meiner Meinung nach statisch und dynamisch,

00:19:47.000 --> 00:19:51.000
wo du einfach weißt, okay, definierst du den Typen im Vorhinein

00:19:51.000 --> 00:19:53.000
oder wird er definiert durch die Verwendung?

00:19:53.000 --> 00:19:56.000
Weak und strong, also schwach und stark

00:19:56.000 --> 00:19:58.000
ist eine sehr

00:19:58.000 --> 00:19:59.000
schwache Bezeichnung

00:19:59.001 --> 00:19:59.000
meiner Meinung nach.

00:20:00.000 --> 00:20:01.000
C zum Beispiel hat ein

00:20:01.000 --> 00:20:04.000
statisches Typsystem, aber ein sehr, sehr

00:20:04.000 --> 00:20:06.000
schwaches. Ob du jetzt einen Character hast oder ein

00:20:06.000 --> 00:20:07.000
Integer oder irgendwas anderes, es ist einfach

00:20:07.000 --> 00:20:10.000
komplett wurscht. Also du kannst alles damit machen.

00:20:10.000 --> 00:20:11.000
Und kannst auch hin und her wechseln und kannst auch

00:20:11.000 --> 00:20:13.000
Bitfiddling mit allem möglichen Scheiß machen.

00:20:14.000 --> 00:20:15.000
Genau, genau, genau. Wundervolle Bühne.

00:20:16.000 --> 00:20:17.000
Und vor dem ist das

00:20:17.000 --> 00:20:19.000
Statische eigentlich das Wichtige, weil es eine bisschen andere

00:20:19.000 --> 00:20:22.000
Herangehensweise ans

00:20:22.000 --> 00:20:22.000
Programmieren

00:20:22.000 --> 00:20:26.000
voraussetzt. Du machst dir

00:20:26.000 --> 00:20:27.000
einfach mehr Gedanken über

00:20:27.000 --> 00:20:30.000
die mögliche Wertemenge

00:20:30.000 --> 00:20:32.000
einer Variable, bevor

00:20:32.000 --> 00:20:34.000
du einen Wert zuweist. Das schließt

00:20:34.000 --> 00:20:36.000
jetzt nicht aus, dass du sagen kannst, hey, du

00:20:36.000 --> 00:20:38.000
bekommst einen Typen durch Typ-Inferenz,

00:20:38.000 --> 00:20:40.000
das mache ich sehr, sehr gerne, weil ich sage, hey,

00:20:40.000 --> 00:20:42.000
diese Variable x ist 3

00:20:42.000 --> 00:20:44.000
und dann weißt du, dass das ein Number oder Integer oder was auch immer

00:20:44.000 --> 00:20:46.000
ist. Das geht natürlich auch, das machen auch

00:20:46.000 --> 00:20:48.000
moderne Programmiersprachen sehr, sehr, sehr gerne.

00:20:50.000 --> 00:20:50.000
Grundlegend,

00:20:50.000 --> 00:20:52.000
dass du halt mit wenig Annotationen machen kannst.

00:20:53.000 --> 00:20:54.000
Nichtsdestotrotz

00:20:54.000 --> 00:20:56.000
definierst du Verträge

00:20:56.000 --> 00:20:58.000
zwischen Bausteinen deines Codes, zwischen den Functions,

00:20:59.000 --> 00:21:01.000
zwischen Methoden in deinen Klassen etc.,

00:21:01.000 --> 00:21:03.000
in denen du sagst, du erwartest aber jetzt diesen Wertebereich

00:21:03.000 --> 00:21:06.000
und nichts anderes und du lässt auch nichts anderes zu.

00:21:06.000 --> 00:21:09.000
Und TypeScript ist meiner Meinung nach doch sehr, sehr spannend,

00:21:10.000 --> 00:21:14.000
weil TypeScript versucht, eine sehr dynamische,

00:21:15.000 --> 00:21:17.000
dynamisch typisierte Programmiersprache

00:21:17.000 --> 00:21:19.000
und generell sehr dynamische Programmiersprache wie JavaScript

00:21:19.000 --> 00:21:22.000
in einer gewissen Art und Weise zu formalisieren.

00:21:22.000 --> 00:21:40.000
Also das Ziel ist ja jetzt nicht dort eine komplett neue Programmiersprache zu definieren oder zu entwickeln, sondern auf Basis einer bestehenden irgendwie ein Regelwerk zu finden, damit alle beteiligten Programmierinnen und Programmierer irgendwas zu diskutieren haben und wissen, was da eigentlich vor sich geht.

00:21:40.000 --> 00:21:54.000
Nichts ist schlimmer, wenn du ein halbes Jahr, nachdem du dein Programm geschrieben hast, wieder zurückgehst und dich fragst, was war denn diese Variable X nochmal? Also was habe ich mir da eigentlich gedacht? Und dann hast du irgendeine fette Wurst an Code und musst herauslesen, was du eigentlich damit machst.

00:21:54.000 --> 00:21:57.000
und also das ist was, was

00:21:57.000 --> 00:21:58.000
mich immer komplett

00:21:58.000 --> 00:21:59.000
verwirrt hat, wie

00:21:59.000 --> 00:22:02.000
ich habe da nie ein funktionales

00:22:02.000 --> 00:22:04.000
Programmierparadigmen ausprobiert,

00:22:04.000 --> 00:22:06.000
viel mit asynchronen Promises gearbeitet in Not,

00:22:07.000 --> 00:22:08.000
irgendwelche dynamischen Objekte

00:22:08.000 --> 00:22:10.000
gehabt, wo ich ständig neue Keys hinzugefügt habe

00:22:10.000 --> 00:22:12.000
und wieder entfernt habe und das war kurz

00:22:12.000 --> 00:22:14.000
und effektiv und schnell und schön

00:22:14.000 --> 00:22:16.000
und drei Monate später habe ich nicht mehr

00:22:16.000 --> 00:22:18.000
gewusst, was ich dort mache, wenn ich das Programm heute lese,

00:22:18.000 --> 00:22:20.000
ich kenne mich nicht aus und ich würde es auch heute

00:22:20.000 --> 00:22:22.000
nicht mehr so machen, einfach weil

00:22:22.000 --> 00:22:28.000
weil, also gut österreichisch, sorry, Graut und Ruben einfach zusammenschmeißen

00:22:28.000 --> 00:22:31.000
und hofft, dass am Ende alles funktioniert.

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

00:22:35.000 --> 00:22:40.000
Aber wenn ihr wirklich mit einem Team versucht, reale Software zu machen,

00:22:40.000 --> 00:22:43.000
dann ist das, glaube ich, die niedrigste Schwelle, die du hast,

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

00:22:50.000 --> 00:22:51.000
Und ich glaube, deswegen sind Typen so wichtig.

00:22:51.000 --> 00:23:18.000
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 Funktionen und je mehr Bibliotheken, die du hast. Wie gesagt, ich wäre schon gesagt, ich bin jetzt in diesem Long-Gen und LLM-Wahnsinn irgendwie gefangen. Da hast du sehr, sehr komplexe Objekte, die du hin und her schickst. 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:18.000 --> 00:23:21.000
Das finde ich auch, also das tatsächlich so als Dokumentationstyp

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

00:23:23.000 --> 00:23:24.000
gerne mag, also in kleinen Closures,

00:23:25.000 --> 00:23:26.000
in kleinen Methoden oder Funktionen irgendwie

00:23:26.000 --> 00:23:29.000
die Argumente so zu annotieren,

00:23:29.000 --> 00:23:31.000
dass beim Riesen klar wird, was denn

00:23:31.000 --> 00:23:32.000
der Mensch da haben möchte, der

00:23:32.000 --> 00:23:33.000
diese API bereitstellt,

00:23:34.000 --> 00:23:36.000
dass ich das irgendwie zusammengebaut kriege oder so, oder

00:23:36.000 --> 00:23:38.000
verstehe, was er denn da braucht oder sowas.

00:23:38.000 --> 00:23:39.000
Das sehe ich anders.

00:23:39.000 --> 00:23:40.000
Ja, ich weiß nicht so.

00:23:44.000 --> 00:23:45.000
Aber das hätte ich ja heute hier.

00:23:46.000 --> 00:23:46.000
Ja, genau.

00:23:48.000 --> 00:24:03.000
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:03.000 --> 00:24:05.000
Aber für mich fällt es auseinander, wenn die Typen

00:24:05.000 --> 00:24:07.000
komplex werden, weil dann hast du

00:24:07.000 --> 00:24:09.000
irgendwelche benannten Typen, die

00:24:09.000 --> 00:24:11.000
irgendwelche interne Struktur haben,

00:24:12.000 --> 00:24:14.000
die völlig opak ist und dann hast du

00:24:14.000 --> 00:24:15.000
17 verschiedene Varianten davon

00:24:15.000 --> 00:24:17.000
und am Ende weißt

00:24:17.000 --> 00:24:19.000
du genauso wenig, was da rein muss und was

00:24:19.000 --> 00:24:21.000
nicht. Und

00:24:21.000 --> 00:24:23.000
das hat alles so seine Grenzen.

00:24:24.000 --> 00:24:25.000
Ja, ich habe letzte

00:24:25.000 --> 00:24:27.000
Woche mit einem Freund telefoniert

00:24:27.000 --> 00:24:29.000
und haben uns auch kurz über

00:24:29.000 --> 00:24:31.000
Type Annotations unterhalten und der meinte so

00:24:31.000 --> 00:24:33.000
ja, schön und gut und ich sehe die Vorteile und so.

00:24:33.000 --> 00:24:35.000
Ich finde es einfach irgendwie hässlich,

00:24:35.000 --> 00:24:37.000
weil irgendwie...

00:24:37.000 --> 00:24:39.000
Das ist ein gutes Argument.

00:24:39.000 --> 00:24:40.000
Die IDE, ja, okay.

00:24:41.000 --> 00:24:42.000
Das ist eigentlich alles gesagt.

00:24:42.000 --> 00:24:44.000
Ästhetisch ist immer das Argument.

00:24:46.000 --> 00:24:47.000
IDE kann damit was anfangen oder so,

00:24:47.000 --> 00:24:48.000
aber wenn man das jetzt anguckt,

00:24:48.000 --> 00:24:51.000
dann hat man bei den ganzen modernen Libraries heutzutage,

00:24:51.000 --> 00:24:53.000
dann hast du da irgendwie Funktionen

00:24:53.000 --> 00:25:04.000
und da hast du pro Zeile einen Parameter weil da kommt immer der Name des Parameters dann kommt halt die Typannotation die einem nicht viel sagt und dann kommt nochmal ein Kommentar

00:25:04.000 --> 00:25:06.000
der erklärt, was die Typannotation einem eigentlich

00:25:06.000 --> 00:25:07.000
sagen will und das dann

00:25:07.000 --> 00:25:09.000
so untereinander. Dann meinte er so, das erinnert mich total

00:25:09.000 --> 00:25:11.000
an C-Code aus den 80ern. Ich weiß

00:25:11.000 --> 00:25:13.000
nicht, ich mag das nicht.

00:25:13.000 --> 00:25:14.000
Das ist nicht peinlich.

00:25:16.000 --> 00:25:17.000
Aber ich muss,

00:25:17.000 --> 00:25:19.000
diesen Argument höre ich auch häufig, wenn man jetzt so bei den

00:25:19.000 --> 00:25:21.000
alten, zum Beispiel

00:25:21.000 --> 00:25:23.000
übernächste Woche wieder, oder

00:25:23.000 --> 00:25:24.000
Das nächste, ich weiß nicht.

00:25:24.000 --> 00:25:25.000
Das nächste, ja.

00:25:25.000 --> 00:25:27.000
Auch hier aufs Python-User.

00:25:27.000 --> 00:25:28.000
Und das nächste, nächste Mittwoch.

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

00:25:29.000 --> 00:25:30.000
Ja, ja.

00:25:30.000 --> 00:25:31.000
Genau, gehen.

00:25:31.000 --> 00:25:34.000
Da gibt es dann die alteingesessenen,

00:25:35.000 --> 00:25:37.000
die sagen auch immer so, ah.

00:25:37.000 --> 00:25:39.000
Immer nur AXE-Quarks, Sternchen, Sternchen.

00:25:39.000 --> 00:25:40.000
Nein, das nicht, aber.

00:25:41.000 --> 00:25:42.000
Ja, ja, aber das ist schon so ein Punkt,

00:25:42.000 --> 00:25:44.000
mit dem viele Probleme haben, ja.

00:25:44.000 --> 00:25:45.000
Ich kenne genug Python,

00:25:46.000 --> 00:25:48.000
dass ich den Witz mit AXE-Quarks verstanden habe.

00:25:49.000 --> 00:25:51.000
Dann gehörst du schon zu den Oberen.

00:25:51.000 --> 00:25:54.000
Ja, also gut.

00:25:56.000 --> 00:25:58.000
Ich bin immer sehr kritisch,

00:25:58.000 --> 00:26:01.000
wenn es darum geht, dass man die Ästhetik

00:26:01.000 --> 00:26:02.000
bewertet, weil

00:26:02.000 --> 00:26:04.000
ich schreibe sehr viel in Rust. Rust ist eine

00:26:04.000 --> 00:26:06.000
sehr unästhetische Sprache. Du hast quasi

00:26:06.000 --> 00:26:08.000
hey, wie viel Syntax kann

00:26:08.000 --> 00:26:10.000
Programmiersprache vertragen? Und Rust sagt ja.

00:26:11.000 --> 00:26:12.000
Also, her damit.

00:26:13.000 --> 00:26:14.000
Aber dafür ist mir halt in Rust

00:26:14.000 --> 00:26:16.000
zu jedem Zeitpunkt absolut

00:26:16.000 --> 00:26:18.000
hundertprozentig klar, was passiert. Und das ist

00:26:18.000 --> 00:26:20.000
halt auch ein Vorteil,

00:26:20.000 --> 00:26:21.000
den man nicht leugnen kann.

00:26:21.000 --> 00:26:23.000
Gerade wenn man in Teams arbeitet. Und da nehme ich halt

00:26:23.000 --> 00:26:25.000
die paar Annotationen, die ich da habe, einfach hin

00:26:25.000 --> 00:26:27.000
und

00:26:27.000 --> 00:26:31.000
irgendwas hat jetzt da geblinkt,

00:26:31.000 --> 00:26:32.000
ich bin kurz rausgekommen

00:26:32.000 --> 00:26:35.000
und verstehe zumindest, was passiert.

00:26:35.000 --> 00:26:37.000
Und ich muss ganz ehrlich sagen, was ich rein jetzt sehe

00:26:37.000 --> 00:26:38.000
von dem, was

00:26:38.000 --> 00:26:41.000
wie Python

00:26:41.000 --> 00:26:42.000
Typings umsetzt,

00:26:43.000 --> 00:26:45.000
ist das eh sehr

00:26:45.000 --> 00:26:47.000
minimalistisch. Also da kann man sich noch

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

00:26:49.000 --> 00:26:51.000
aber so hässlich.

00:26:52.000 --> 00:26:53.000
Ja, ich

00:26:53.000 --> 00:26:55.000
finde das Problem ist halt,

00:26:55.000 --> 00:26:57.000
dass diese Typsysteme

00:26:57.000 --> 00:26:59.000
oft zu weit getrieben werden

00:26:59.000 --> 00:27:01.000
und das treibt dann Blüten.

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

00:27:03.000 --> 00:27:05.000
Genau, für alles und jedes und es muss dann alles ein benannter

00:27:05.000 --> 00:27:07.000
Typ sein und das geht dann,

00:27:07.000 --> 00:27:08.000
also ich habe hier

00:27:08.000 --> 00:27:10.000
ein Beispiel aus der

00:27:10.000 --> 00:27:13.000
Apple-Dokumentation, da gibt es einen Typen,

00:27:13.000 --> 00:27:15.000
der heißt CN Label Contact Relation

00:27:15.000 --> 00:27:17.000
Younger Cousin, Mother, Siblings, Daughter or Father,

00:27:17.000 --> 00:27:17.000
Sisters, Daughter.

00:27:17.000 --> 00:27:19.000
Ja. Ist ein Typ.

00:27:19.000 --> 00:27:21.000
Ja, ob man den jetzt braucht oder nicht.

00:27:22.000 --> 00:27:23.000
Auf der anderen Seite

00:27:23.000 --> 00:27:25.000
ein Beispiel aus der .NET

00:27:25.000 --> 00:27:27.000
Bibliothek.

00:27:27.000 --> 00:27:29.000
Die Links sind dann alle in den Show Notes.

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

00:27:31.000 --> 00:27:33.000
Die hat 30 Argumente.

00:27:34.000 --> 00:27:35.000
31. Das erste ist ein

00:27:35.000 --> 00:27:37.000
Object, das heißt Makro. Das zweite ist ein Object,

00:27:37.000 --> 00:27:38.000
das heißt Arc1.

00:27:39.000 --> 00:27:41.000
Das dritte ist ein Object, das heißt Arc2.

00:27:41.000 --> 00:27:42.000
Und so geht es weiter bis Arc30.

00:27:44.000 --> 00:27:45.000
Grandios. Da bringen mir die Typen nichts.

00:27:45.000 --> 00:27:47.000
Da sagen mir die Typen nicht,

00:27:47.000 --> 00:27:49.000
was das macht.

00:27:49.000 --> 00:27:51.000
Und zwar in beide Richtungen nicht.

00:27:51.000 --> 00:27:53.000
Und es gibt halt da diese Fetischisten, die sagen,

00:27:53.000 --> 00:27:55.000
du musst aber überall benannte Typen drin haben

00:27:55.000 --> 00:27:58.000
und du musst das Typsystem vollständig

00:27:58.000 --> 00:27:58.000
ausnutzen.

00:27:59.000 --> 00:28:01.000
Und das geht mir genauso auf den Senkel wie die alten

00:28:01.000 --> 00:28:03.000
Herren, die dann sagen, nein,

00:28:04.000 --> 00:28:05.000
Typ-Annotationen ist

00:28:05.000 --> 00:28:07.000
ekelhaft und hässlich und wie in den 80ern.

00:28:08.000 --> 00:28:09.000
Irgendwo in der Mitte ist dieses Maß

00:28:09.000 --> 00:28:10.000
und

00:28:10.000 --> 00:28:13.000
Du hast mich gerade an etwas Wunderbares erinnert.

00:28:13.000 --> 00:28:14.000
Ich bin ja

00:28:14.000 --> 00:28:17.000
in einer Java-Welt groß geworden.

00:28:17.000 --> 00:28:19.000
und habe gelitten.

00:28:20.000 --> 00:28:20.000
Ich auch.

00:28:23.000 --> 00:28:25.000
Ich komme aus der Nähe von Linz

00:28:25.000 --> 00:28:27.000
und direkt auf dem anderen Bergerl

00:28:27.000 --> 00:28:29.000
gegenüber wohnt

00:28:29.000 --> 00:28:31.000
einer der Erfinder vom

00:28:31.000 --> 00:28:33.000
Spring Framework. Also wir kennen uns,

00:28:33.000 --> 00:28:35.000
unsere Kinder gehen gemeinsam in die Schule und solche Sachen

00:28:35.000 --> 00:28:37.000
und da gibt es eine Klasse, das ist

00:28:37.000 --> 00:28:39.000
die Has This Type Pattern Try

00:28:39.000 --> 00:28:41.000
to Sneak in Some Generic or Parameterize

00:28:41.000 --> 00:28:43.000
Type Pattern Matching Stuff Anywhere Visitor.

00:28:44.000 --> 00:28:44.000
Und das ist

00:28:44.000 --> 00:28:47.000
fantastisch. Also bei uns

00:28:47.000 --> 00:28:48.000
in der Firma, ohne Java-Developer,

00:28:49.000 --> 00:28:51.000
bei uns in der Firma, ohne Java-Developer,

00:28:51.000 --> 00:28:53.000
diese Weißkin-Monitore, aber nicht,

00:28:53.000 --> 00:28:55.000
dass sie irgendwie dort mehrere Fenster

00:28:55.000 --> 00:28:57.000
nebeneinander hinkriegen, sondern ich sage immer, das ist,

00:28:57.000 --> 00:28:59.000
damit sie die Klassennamen ohne

00:28:59.000 --> 00:29:01.000
Zeilenhundbruch durchstehen können.

00:29:02.000 --> 00:29:03.000
Und das ist natürlich,

00:29:03.000 --> 00:29:05.000
das ist Mumpitz, das ist ganz klar.

00:29:05.000 --> 00:29:08.000
Ich denke, man muss die ganzen Sachen immer ein bisschen

00:29:08.000 --> 00:29:09.000
pragmatischer sehen

00:29:09.000 --> 00:29:11.000
und halt auch einen richtigen

00:29:11.000 --> 00:29:13.000
Nutzen oder wissen, welchen

00:29:13.000 --> 00:29:15.000
Nutzen man daraus zieht. Das gilt für

00:29:15.000 --> 00:29:17.000
alles in der Softwareentwicklung, meiner Meinung nach.

00:29:17.000 --> 00:29:47.000
Ja, das ist ein Dankzeug.

00:29:47.000 --> 00:30:03.000
Und um das geht es eigentlich Und gerade in TypeScript also gerade auch in meinem Buch gibt es ein paar Beispiele drinnen da kommen sie schon richtig richtig vorausgekommen Da gibt es irrsinnig m Werkzeuge wie String Literal Types oder Tappel Variadic Das sind Dinge wo ich mir denke

00:30:04.000 --> 00:30:06.000
Wahnsinn, dass das überhaupt geht.

00:30:06.000 --> 00:30:08.000
Also beeindruckend technisch, dass das geht.

00:30:08.000 --> 00:30:09.000
Aber die Use-Cases

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

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

00:30:13.000 --> 00:30:15.000
drei Lektionen, wo wir

00:30:15.000 --> 00:30:18.000
ein funktionales

00:30:18.000 --> 00:30:19.000
Programmiertool wie

00:30:19.000 --> 00:30:21.000
Currying versuchen, auf drei

00:30:21.000 --> 00:30:23.000
sehr, sehr komplexe Orten umzusetzen und sagen,

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

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

00:30:32.000 --> 00:30:37.000
aber genauso einfach zu verwenden ist und die einfach zu typisieren ist,

00:30:37.000 --> 00:30:40.000
mit der du besser die Typinformationen rauskriegst.

00:30:41.000 --> 00:30:43.000
Und das stelle ich dann auch so zur Diskussion.

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

00:30:49.000 --> 00:30:50.000
und wie weit treibst du das?

00:30:51.000 --> 00:30:53.000
Ja, ich glaube, das ist tatsächlich gar nicht so einfach herauszufinden.

00:30:53.000 --> 00:31:16.000
Ja, und ich glaube aber, dass da noch ein anderes Problem dahinter ist. Und ich bin sehr froh, Stefan, dass du da gesagt hast, dass du gegen Tests bist oder gegen große Testcoverage. Und du hast jetzt gerade eben so ein bisschen deinen Ansatz beschrieben, wie du Programme schreibst. Und du hast das gesagt, was meiner Meinung nach ganz wichtig ist. Du hast gesagt, du fängst an, ein Programm zu schreiben und weißt noch nicht, wie es am Ende ausschauen wird.

00:31:16.000 --> 00:31:19.000
und das geht mir genauso

00:31:19.000 --> 00:31:21.000
und das ist einer der Gründe,

00:31:21.000 --> 00:31:22.000
warum ich

00:31:22.000 --> 00:31:25.000
Python mag,

00:31:25.000 --> 00:31:27.000
weil mir das die Freiheit gibt,

00:31:27.000 --> 00:31:29.000
da so explorativ rumzugehen, ohne

00:31:29.000 --> 00:31:31.000
mir groß Gedanken machen zu müssen,

00:31:31.000 --> 00:31:32.000
wie es denn jetzt sauber zusammenpasst

00:31:32.000 --> 00:31:35.000
und ich glaube, dass das ein Programmierstil ist,

00:31:35.000 --> 00:31:37.000
ich nenne das exploratives Programmieren,

00:31:37.000 --> 00:31:39.000
ich muss so ein bisschen diesen Space

00:31:39.000 --> 00:31:41.000
erkunden, muss so ein bisschen sehen, was kann

00:31:41.000 --> 00:31:43.000
ich, was schaffe ich, was mache ich

00:31:43.000 --> 00:31:45.000
und das ist halt mein Stil,

00:31:45.000 --> 00:32:03.000
Ich gehe da rein und sage, jetzt machen wir erstmal irgendwas. Es gibt aber auch Leute, die da vielleicht mathematischer rangehen und die sagen, okay, ich habe hier einen Plan und eigentlich auf dem Papier habe ich es ja schon hingeschrieben, dann kann ich auch die Tests zuerst schreiben, weil ich weiß ja schon, was das machen soll. Ich weiß ja schon, wie es am Ende ausschaut. Oder ich kann gleich die richtigen Typen reinschreiben.

00:32:03.000 --> 00:32:09.000
Ja, da müssen wir uns ja das Akkord nicht verändern und einfach Type-Driven-Development, eine neue Instanz starten.

00:32:09.000 --> 00:32:09.000
mir.

00:32:11.000 --> 00:32:11.000
Und

00:32:11.000 --> 00:32:15.000
ja, das sind glaube ich

00:32:15.000 --> 00:32:17.000
einfach zwei verschiedene Arten zu

00:32:17.000 --> 00:32:19.000
programmieren, die eben verschiedene Dinge

00:32:19.000 --> 00:32:20.000
eher bevorzugen.

00:32:21.000 --> 00:32:23.000
Es ist tatsächlich

00:32:23.000 --> 00:32:25.000
glaube ich auch ein bisschen von der Sprache abhängig, weil

00:32:25.000 --> 00:32:27.000
also ich glaube Python und JavaScript

00:32:27.000 --> 00:32:29.000
unterstützen ja diese Art des explorativen

00:32:29.000 --> 00:32:30.000
Programmierens sehr, sehr stark. Einfach eben

00:32:30.000 --> 00:32:32.000
in dem sie die Typen auch entfernen.

00:32:33.000 --> 00:32:35.000
Du kannst sie wirklich einfach mal herumprobieren und schauen,

00:32:35.000 --> 00:32:37.000
was rauskommt und schauen,

00:32:37.000 --> 00:32:39.000
wie weit du mit

00:32:39.000 --> 00:32:40.000
deinen Ideen kommst.

00:32:41.000 --> 00:32:43.000
Was ich spannend finde, also ich bin

00:32:43.000 --> 00:32:45.000
jetzt seit einigen Jahren auch sehr, sehr stark in Rust drin,

00:32:45.000 --> 00:32:47.000
ich habe das jetzt schon erwähnt, und sorry, das ist der

00:32:47.000 --> 00:32:49.000
klassische Rust-Nutzer, nicht ständig

00:32:49.000 --> 00:32:50.000
sagen, dass er Rust verwendet, aber

00:32:50.000 --> 00:32:53.000
es ist halt wirklich so. Die Sprache macht einiges

00:32:53.000 --> 00:32:55.000
sehr, sehr richtig. Du hast in Rust eine sehr

00:32:55.000 --> 00:32:57.000
stark typisierte

00:32:57.000 --> 00:32:59.000
Programmiersprache mit einem fantastischen

00:32:59.000 --> 00:33:01.000
Typsystem. Das ist grandios,

00:33:01.000 --> 00:33:02.000
dass das so funktioniert,

00:33:02.000 --> 00:33:05.000
wie es funktioniert. Das heißt, du kannst dir gar nicht

00:33:05.000 --> 00:33:06.000
leisten, dass du einfach nur mehr schaust,

00:33:06.000 --> 00:33:08.000
hey, was, wo

00:33:08.000 --> 00:33:12.000
Wo kommst du mit deinen Wertebereichen überhaupt am Ende hin?

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

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

00:33:20.000 --> 00:33:24.000
weil die Typen, die vor Hause schon drinnen sind, so entgegenkommen sind.

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

00:33:27.000 --> 00:33:30.000
und den üblichen Wertebereichen schon sehr, sehr weit,

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

00:33:37.000 --> 00:33:39.000
auseinander überlegen musst.

00:33:39.000 --> 00:33:41.000
Und das ist sehr, sehr spannend. Es ist aber

00:33:41.000 --> 00:33:43.000
trotzdem ein anderer Wert des Programmierens.

00:33:43.000 --> 00:33:45.000
Also das

00:33:45.000 --> 00:33:47.000
Endresultat schaut auch dann

00:33:47.000 --> 00:33:49.000
anders aus. Also ich mag das aber auch gerne,

00:33:49.000 --> 00:33:51.000
so Models oder so Dataclasses

00:33:51.000 --> 00:33:53.000
irgendwie zu bauen und dann zu gucken, hey, was sind das

00:33:53.000 --> 00:33:55.000
denn überhaupt für Objekte und dir halt dann direkt zur

00:33:55.000 --> 00:33:57.000
Annotation zu verwenden, das ist so

00:33:57.000 --> 00:33:59.000
strukturell sehr klar.

00:34:00.000 --> 00:34:01.000
Nein, es schließt sich auch nicht aus.

00:34:01.000 --> 00:34:02.000
Also es ist,

00:34:02.000 --> 00:34:05.000
ich denke mir,

00:34:05.000 --> 00:34:08.000
die Gefahr liegt wahrscheinlich, dass man sich auf

00:34:08.000 --> 00:34:10.000
eines komplett verschreibt.

00:34:12.000 --> 00:34:12.000
Auch das, was der

00:34:12.000 --> 00:34:14.000
Johannes wieder gesagt hat, ganz richtig ist,

00:34:15.000 --> 00:34:17.000
es ist am Ende des Tages

00:34:17.000 --> 00:34:18.000
ein Werkzeug und es muss irgendeinen

00:34:18.000 --> 00:34:20.000
Job erfüllen.

00:34:21.000 --> 00:34:22.000
Und wenn das gut funktioniert, dass du

00:34:22.000 --> 00:34:24.000
dir vorher Gedanken darüber machst, welche Daten

00:34:24.000 --> 00:34:27.000
du benötigst, dann ist das absolut legitim

00:34:27.000 --> 00:34:27.000
meiner Meinung nach.

00:34:27.000 --> 00:34:30.000
Ich finde es gerade so

00:34:30.000 --> 00:34:32.000
angenehm. Wichtig ist, dass

00:34:32.000 --> 00:34:34.000
die Sprache mit der du arbeitest, das unterstützt.

00:34:35.000 --> 00:34:36.000
Ja, ich glaube auch eben.

00:34:38.000 --> 00:34:40.000
Aber ich meine, das hat natürlich mal einen Preis,

00:34:40.000 --> 00:34:43.000
weil es halt zusätzliche Komplexität unter Umständen halt auch einführt

00:34:43.000 --> 00:34:45.000
und es dann halt vielleicht auch unzugänglicher macht.

00:34:45.000 --> 00:34:48.000
Also worauf ich eigentlich hinaus will, ist,

00:34:49.000 --> 00:34:53.000
naja, je nach Use Case kann es halt unterschiedlich nützlich sein.

00:34:53.000 --> 00:35:03.000
Also wenn man halt zum Beispiel eben in einem Team an einer gro Software schreibt dann kann es halt sein dass es sehr viel bringt auch irgendwie m viele H zu errichten

00:35:04.000 --> 00:35:05.000
bevor irgendwie Code ...

00:35:05.000 --> 00:35:07.000
Du willst quasi gar nicht, dass die Entwickler irgendwas machen.

00:35:07.000 --> 00:35:10.000
Ja, das ist leider halt eine Strategie,

00:35:10.000 --> 00:35:12.000
das ist schwer zu unterscheiden von ...

00:35:12.000 --> 00:35:14.000
Man versucht, Fehler zu vermeiden,

00:35:14.000 --> 00:35:15.000
bevor sie dann produktiv gehen,

00:35:15.000 --> 00:35:18.000
zu bloß nicht deployen, was dann halt auch viele Leute machen,

00:35:19.000 --> 00:35:22.000
was halt irgendwie auch blöde Konsequenzen hat unter Umständen dann.

00:35:22.000 --> 00:35:24.000
weil also viele Sachen, also man hat dann zum Beispiel

00:35:24.000 --> 00:35:26.000
nicht nur ein Staging-System, sondern noch so

00:35:26.000 --> 00:35:27.000
drei andere oder vier andere und führt immer

00:35:27.000 --> 00:35:30.000
mehr hinzu, sodass man bloß nicht nach

00:35:30.000 --> 00:35:31.000
Produktionen deployen muss.

00:35:31.000 --> 00:35:33.000
Ich habe zwei Abteilungen bei uns kennengelernt,

00:35:34.000 --> 00:35:36.000
die haben Reployment-Release-Zyklus so

00:35:36.000 --> 00:35:36.000
alle sechs Monate.

00:35:37.000 --> 00:35:40.000
Ja, genau, in den sechs Monaten passiert halt auch

00:35:40.000 --> 00:35:42.000
nichts, aber ja, ist halt

00:35:42.000 --> 00:35:44.000
vielleicht auch irgendwie ein Konflikt mit anderen

00:35:44.000 --> 00:35:46.000
Zielen. Hast du etwa diesen

00:35:46.000 --> 00:35:48.000
Artikel über Move Fast and Break Things gelesen,

00:35:48.000 --> 00:35:49.000
der kürzlich rausgekommen ist?

00:35:49.000 --> 00:35:49.000
Ja, genau.

00:35:49.000 --> 00:35:52.000
Ja, richtig.

00:35:52.000 --> 00:35:54.000
Und genau,

00:35:54.000 --> 00:35:56.000
also an der Stelle macht es ja vielleicht,

00:35:56.000 --> 00:35:57.000
wenn man in so einer Situation ist,

00:35:58.000 --> 00:35:59.000
sehr viel Sinn da,

00:36:00.000 --> 00:36:02.000
von den Leuten zu verlangen, dass sie sich erst Gedanken machen

00:36:02.000 --> 00:36:04.000
und dass halt man versucht, möglichst viele Fehler

00:36:04.000 --> 00:36:06.000
zu fangen, bevor sie halt

00:36:06.000 --> 00:36:08.000
in der Produktion aufschlagen, weil

00:36:08.000 --> 00:36:10.000
da ist es halt viel teurer, sie halt zu entfernen

00:36:10.000 --> 00:36:12.000
als, aber es kann

00:36:12.000 --> 00:36:14.000
halt total anders sein, wenn jetzt jemand zum Beispiel

00:36:14.000 --> 00:36:15.000
und das ist halt eine der Stärken bei

00:36:15.000 --> 00:36:18.000
Python, bei JavaScript auch

00:36:18.000 --> 00:36:19.000
ein bisschen anders,

00:36:19.000 --> 00:36:23.000
dass es halt vor allen Dingen auch von Leuten benutzt wird,

00:36:23.000 --> 00:36:26.000
die sich selber gar nicht als professionelle Programmierer sehen würden,

00:36:26.000 --> 00:36:27.000
sondern die eher sagen würden,

00:36:27.000 --> 00:36:30.000
naja, ich bin eigentlich eher so Data Scientist

00:36:30.000 --> 00:36:32.000
oder ein Analyst oder sowas.

00:36:32.000 --> 00:36:34.000
Oder halt irgendwie jemand,

00:36:34.000 --> 00:36:37.000
der irgendwie, keine Ahnung, Roboter irgendwie dazu bringt,

00:36:37.000 --> 00:36:38.000
irgendwie lustige Dinge zu machen oder sowas.

00:36:39.000 --> 00:36:41.000
Oder Teilchenbeschleuniger.

00:36:41.000 --> 00:36:43.000
Oder Teilchenbeschleuniger, also solche Sachen, genau.

00:36:43.000 --> 00:36:47.000
Und ich will gar nicht jetzt irgendwie Typtheorie verstehen

00:36:47.000 --> 00:36:50.000
oder irgendwie, keine Ahnung,

00:36:50.000 --> 00:36:51.000
auch Unit-Tests.

00:36:51.000 --> 00:36:53.000
Und da sind wir auch bei einem Ding, wo die Sachen

00:36:53.000 --> 00:36:56.000
so ein bisschen ähnlich sind. Also ich dachte auch lange Zeit

00:36:56.000 --> 00:36:56.000
irgendwie,

00:36:58.000 --> 00:36:59.000
Unit-Tests sind was ganz anderes und

00:36:59.000 --> 00:37:00.000
Typisierung

00:37:00.000 --> 00:37:03.000
ist ein anderes Ende

00:37:03.000 --> 00:37:05.000
von einem Spektrum und ich bin eher so Team-Test.

00:37:06.000 --> 00:37:07.000
Aber inzwischen denke ich so, naja, das ist schon

00:37:07.000 --> 00:37:09.000
relativ ähnlich auch. Ich meine, auch Unit-Testing

00:37:09.000 --> 00:37:11.000
ist halt so eine Sache, die man sich erst irgendwie

00:37:11.000 --> 00:37:13.000
erschließen muss und für manche Leute macht

00:37:13.000 --> 00:37:15.000
es einfach, wenn man halt irgendwie so

00:37:15.000 --> 00:37:17.000
in einem Jupyter-Notebook Sachen macht,

00:37:17.000 --> 00:37:34.000
Und ja, manchmal macht es schon Sinn, das zu testen, aber für viele Leute ist es auch nicht, lohnt es sich, weiß ich nicht, ob es sich wirklich lohnt, da so tief einzusteigen. Und aber ich meine, klar, wenn man jetzt große Software im Team entwickelt, dann klar hat man Tests und eine CI-Pipeline und weiß ich nicht, diesen ganzen Kram halt.

00:37:34.000 --> 00:37:52.000
Ja, das Stichwort da ist doch Programming by Contract, oder? Und das ist halt eine Möglichkeit, so einen Contract zu schreiben. Aber ich bin da in so einem Zwiespalt. Einerseits bin ich total genervt von solchen Typsystemen, die dann sehr präzise sind. Ich bin auch mit Java aufgewachsen, Stefan, also ich zähle deinen Schmerz.

00:37:52.000 --> 00:37:54.000
und dann

00:37:54.000 --> 00:37:57.000
wirkt man sich ab und macht ein Pair

00:37:57.000 --> 00:37:58.000
aus int und

00:37:58.000 --> 00:38:01.000
string und dann weißt du aber nicht, wie du an den zweiten

00:38:01.000 --> 00:38:03.000
drankommst und ach, das ist alles ganz

00:38:03.000 --> 00:38:05.000
schön. Aber auf der anderen

00:38:05.000 --> 00:38:07.000
Seite gibt es nicht

00:38:07.000 --> 00:38:09.000
die Möglichkeit zu sagen, ganz triviale

00:38:09.000 --> 00:38:11.000
Sachen zu sagen. Zum Beispiel hier muss eine

00:38:11.000 --> 00:38:12.000
Zahl rauskommen, die immer größer ist als 0.

00:38:13.000 --> 00:38:15.000
Oder immer kleiner als 0. Größer als 0 geht ja tatsächlich

00:38:15.000 --> 00:38:17.000
noch, aber kleiner als 0 kannst

00:38:17.000 --> 00:38:19.000
du nicht sagen. Du kannst nicht sagen, hier muss was rauskommen,

00:38:19.000 --> 00:38:20.000
was zwischen 0 und 1 liegt.

00:38:20.000 --> 00:38:22.000
und das ist irgendwie so

00:38:22.000 --> 00:38:24.000
eine weirde Sache.

00:38:24.000 --> 00:38:26.000
Ich bin da so im Zwiespalt. Ich hätte gerne

00:38:26.000 --> 00:38:28.000
keine Typsysteme, aber wenn ich Typsysteme hätte,

00:38:28.000 --> 00:38:30.000
hätte ich gerne so welche, die so exakt sind,

00:38:31.000 --> 00:38:33.000
dass ich sowas sagen kann

00:38:33.000 --> 00:38:34.000
und dass mir dann auch der Compiler sagen kann,

00:38:34.000 --> 00:38:36.000
Moment, hier rufst du eine Funktion aus mit einer Zahl,

00:38:37.000 --> 00:38:38.000
die zwischen 0 und 1 sein kann,

00:38:39.000 --> 00:38:40.000
aber die muss zwischen 0 und

00:38:40.000 --> 00:38:41.000
minus 1 sein.

00:38:41.000 --> 00:38:44.000
Nee, das ist nicht Validierung, sondern das ist

00:38:44.000 --> 00:38:46.000
nee, das sind sogenannte Value Types, das kannst du auch

00:38:46.000 --> 00:38:48.000
in ein Typsystem reingießen, wenn du das möchtest.

00:38:48.000 --> 00:39:18.000
Ja, das ist quasi keine Sprache.

00:39:18.000 --> 00:39:20.000
auch tatsächlich irgendwelche Bytes liegen,

00:39:20.000 --> 00:39:22.000
die von einer CPU ausgelesen werden.

00:39:23.000 --> 00:39:23.000
Also das,

00:39:24.000 --> 00:39:26.000
wenn dir das

00:39:26.000 --> 00:39:28.000
Typsystem das erlaubt, dass du dort

00:39:28.000 --> 00:39:30.000
irgendwas zwischen minus 1 und plus 1 zum Beispiel

00:39:30.000 --> 00:39:32.000
definierst oder mein Gott,

00:39:32.000 --> 00:39:34.000
eine ganze Zeit zwischen 25, was auch immer,

00:39:35.000 --> 00:39:36.000
dann schiebst du die

00:39:36.000 --> 00:39:38.000
Validierungen nur an eine andere Stelle.

00:39:39.000 --> 00:39:40.000
Ja gut, aber das

00:39:40.000 --> 00:39:42.000
macht man mit dem Typsystem generell, oder?

00:39:42.000 --> 00:39:44.000
Also ich meine, sobald der TypeScript-Compiler durch ist,

00:39:44.000 --> 00:39:46.000
ist er weg. Das ist

00:39:46.000 --> 00:39:48.000
sehr richtig, genau. Das ist sehr richtig.

00:39:48.000 --> 00:39:50.000
Ich glaube, in Python genauso, wenn ich mich nicht täusche.

00:39:50.000 --> 00:39:51.000
Ja, generell.

00:39:51.000 --> 00:39:53.000
In Python sind die Annotationen erstmal gar nichts.

00:39:54.000 --> 00:39:56.000
Genau, das ist in Python auch so leicht anders.

00:39:56.000 --> 00:39:57.000
Das wissen ja auch viele Leute.

00:39:57.000 --> 00:39:59.000
Ja, das ist ganz, das ist halt, wenn man...

00:39:59.001 --> 00:40:01.000
zu den praktischen Dingen kommt, die halt damit problematisch

00:40:01.000 --> 00:40:03.000
sind. Also ich bin ja häufiger auch irgendwie

00:40:03.000 --> 00:40:03.000
in unterschiedlichen

00:40:03.000 --> 00:40:07.000
Firmenkontexten da so unterwegs und

00:40:07.000 --> 00:40:09.000
das, was ich in letzter Zeit

00:40:09.000 --> 00:40:11.000
halt häufig sehe, ist halt sowas wie

00:40:11.000 --> 00:40:13.000
Leute annotieren halt

00:40:13.000 --> 00:40:15.000
irgendwie ganz viel, aber

00:40:15.000 --> 00:40:17.000
sie haben

00:40:17.000 --> 00:40:19.000
keinen statischen Type-Checker, der da drüber

00:40:19.000 --> 00:40:20.000
laufen würde und in Python ist halt auch keiner eingebaut,

00:40:21.000 --> 00:40:22.000
was vielleicht auch nicht so gut ist

00:40:22.000 --> 00:40:24.000
und man müsste da, und dann

00:40:24.000 --> 00:40:26.000
mache ich dann sowas wie, ich lasse mal MyPy drüber

00:40:26.000 --> 00:40:28.000
laufen und die Leute verwenden alle

00:40:28.000 --> 00:40:30.000
TypeDict und sowas und denken halt, ja, das

00:40:30.000 --> 00:40:32.000
überprüft jetzt, ob meine ganzen Werte da so

00:40:32.000 --> 00:40:35.000
meine ganzen Werte

00:40:35.000 --> 00:40:36.000
in dem Dict halt so den richtigen

00:40:36.000 --> 00:40:38.000
Typ haben und so.

00:40:39.000 --> 00:40:40.000
Und Python selber macht da gar nichts.

00:40:41.000 --> 00:40:42.000
Das überprüft überhaupt nichts. Das ignoriert

00:40:42.000 --> 00:40:44.000
die Annotationen einfach. Ich lasse dann

00:40:44.000 --> 00:40:46.000
MyPyte rüberlaufen und kriege dann so 400 Fehler.

00:40:47.000 --> 00:40:48.000
Und dann denke ich mir so, okay, ja, also

00:40:48.000 --> 00:40:50.000
du hast da schön deine Annahmen darüber, wie die ganzen Typen

00:40:50.000 --> 00:40:52.000
aussehen, dokumentiert, aber die sind halt leider alle falsch.

00:40:53.000 --> 00:40:54.000
Das stimmt überhaupt gar nicht.

00:40:54.000 --> 00:40:56.000
Und ja, da denkt man sich, warum hat man

00:40:56.000 --> 00:40:58.000
sich überhaupt die Mühe gemacht. Also es ist halt irgendwie

00:40:58.000 --> 00:41:00.000
Ja, wie ist denn

00:41:00.000 --> 00:41:03.000
der Zustand der Entwicklungsumgebungen

00:41:03.000 --> 00:41:04.000
in Python?

00:41:05.000 --> 00:41:07.000
Kommt drauf an. Also auch die

00:41:07.000 --> 00:41:08.000
hängen halt daran, ob du

00:41:08.000 --> 00:41:10.000
MyPy zum Beispiel als Static Tideshaper

00:41:10.000 --> 00:41:12.000
Extension richtig konfiguriert hast.

00:41:13.000 --> 00:41:14.000
Ja, und ob dann auch

00:41:14.000 --> 00:41:16.000
MyPy die Stubs halt

00:41:16.000 --> 00:41:18.000
lesen kann, die halt da notwendig sind

00:41:18.000 --> 00:41:19.000
oder halt auch nicht.

00:41:20.000 --> 00:41:22.000
Aber viele IDEs behandelt es doch auch selber schon.

00:41:22.000 --> 00:41:24.000
Ja, ja, genau. Da gibt es ja auch

00:41:24.000 --> 00:41:26.000
dann, ich weiß gar nicht jetzt,

00:41:26.000 --> 00:41:27.000
bei VS Code

00:41:27.000 --> 00:41:29.000
dann normalerweise verwendet wird.

00:41:29.000 --> 00:41:30.000
MyPy ist eine Extension.

00:41:31.000 --> 00:41:33.000
Ja, aber ich meine, wenn jetzt zum Beispiel einfach nur das...

00:41:33.000 --> 00:41:35.000
Also IntelliJ macht das selber.

00:41:35.000 --> 00:41:38.000
Ja, die haben einen proprietären, dann gibt es irgendwie MyPy,

00:41:38.000 --> 00:41:40.000
klar, und es gibt halt

00:41:40.000 --> 00:41:41.000
noch PyWrite und

00:41:41.000 --> 00:41:44.000
der Language Server für Python.

00:41:45.000 --> 00:41:45.000
Kann es sein, dass der selber

00:41:45.000 --> 00:41:48.000
von Microsoft in TypeScript

00:41:48.000 --> 00:41:49.000
geschrieben ist? Ich glaube schon.

00:41:50.000 --> 00:41:52.000
Ja, es ist nämlich spannend,

00:41:52.000 --> 00:41:54.000
weil ich denke,

00:41:55.000 --> 00:41:56.000
TypeScript hat da einige

00:41:56.000 --> 00:41:58.000
richtige Entscheidungen getroffen auf dem Gebiet.

00:41:59.000 --> 00:42:00.000
Die ihr jetzt

00:42:00.000 --> 00:42:02.000
alle angesprochen habt, was kompliziert

00:42:02.000 --> 00:42:04.000
und was komplex in Python ist,

00:42:04.000 --> 00:42:05.000
nämlich,

00:42:06.000 --> 00:42:07.000
dass die Sprache dir zwar ein

00:42:07.000 --> 00:42:09.000
Typsystem anbietet,

00:42:10.000 --> 00:42:12.000
cool, aber eigentlich nichts damit macht,

00:42:12.000 --> 00:42:13.000
sondern du brauchst eh nur einen extra Typchecker

00:42:13.000 --> 00:42:16.000
und anscheinend wie bei den Package-Managern

00:42:16.000 --> 00:42:17.000
gibt es dort auch mehrere, wo du

00:42:17.000 --> 00:42:20.000
dir dann noch aussuchen kannst, welcher gefällt dir jetzt

00:42:20.000 --> 00:42:22.000
und welcher passt zu dir

00:42:22.000 --> 00:42:24.000
und so weiter und ich finde das grandios, dass es

00:42:24.000 --> 00:42:26.000
Auswahl gibt, keine Frage, aber es erhöht natürlich

00:42:26.000 --> 00:42:27.000
auch die Komplexität.

00:42:27.000 --> 00:42:28.000
Und TypeScript hat,

00:42:29.000 --> 00:42:31.000
TypeScript selbst ist ja eigentlich

00:42:31.000 --> 00:42:33.000
mehrere Dinge. Es ist zum einen einmal

00:42:33.000 --> 00:42:35.000
ein Typsystem, cool, also wie werden

00:42:35.000 --> 00:42:37.000
Typen geschrieben, definiert, wie

00:42:37.000 --> 00:42:39.000
sind sie im Zusammenhang. Es ist auch ein

00:42:39.000 --> 00:42:40.000
Typchecker dabei,

00:42:41.000 --> 00:42:43.000
also der TypeScript-Compiler

00:42:43.000 --> 00:42:45.000
TSC macht in erster Linie mal

00:42:45.000 --> 00:42:47.000
Typechecking, aber

00:42:47.000 --> 00:42:49.000
kompiliert dann auch tatsächlich JavaScript-Code,

00:42:49.000 --> 00:42:51.000
den du ausführen kannst. Also es gibt so jetzt

00:42:51.000 --> 00:42:53.000
Proposals, dass du auch Typ-Annotationen

00:42:53.000 --> 00:42:56.000
irgendwann einmal in JavaScript schreiben können solltest,

00:42:56.000 --> 00:42:58.000
ähnlich wie in Python, wir sind dort einfach von der Runtime ignoriert.

00:42:59.000 --> 00:43:01.000
Aber da sind wir noch nicht, also da kommen wir erst hin.

00:43:02.000 --> 00:43:03.000
Das heißt, du brauchst auch den Compiler.

00:43:03.000 --> 00:43:05.000
Das heißt, wir haben ein Typ-System, Typ-Checker, Compiler

00:43:05.000 --> 00:43:08.000
und noch auch, ganz, ganz wichtig, eine Integration in Editoren

00:43:08.000 --> 00:43:09.000
und Entwicklungsumgebungen.

00:43:10.000 --> 00:43:15.000
Und das war eigentlich, also dieser gesamte Tooling-Aspekt rundherum,

00:43:15.000 --> 00:43:19.000
nicht nur das Typ-System anzubieten, sondern auch Werkzeuge anzubieten,

00:43:19.000 --> 00:43:23.000
dass du nachher zu validen JavaScript-Code kommst und du deine Fehler siehst,

00:43:23.000 --> 00:43:27.000
und die Fehler auch sofort in deinem Editor und deiner IDE dargestellt werden,

00:43:28.000 --> 00:43:30.000
sind meiner Meinung nach genau die Punkte,

00:43:30.000 --> 00:43:32.000
die noch auch den, unter Anführungszeichen,

00:43:33.000 --> 00:43:38.000
Ziegelszug von TypeScript auch zu verantworten gehabt haben.

00:43:39.000 --> 00:43:42.000
Weil ohne dem hast du halt nur die Hälfte der Dinge.

00:43:42.000 --> 00:43:46.000
Du brauchst halt irgendwie alles, damit du sauber entwickeln kannst.

00:43:47.000 --> 00:43:50.000
Und wenn ich mir denke, dass ich Visual Studio Code aufmache,

00:43:50.000 --> 00:43:51.000
wo TypeScript schon drinnen ist,

00:43:51.000 --> 00:43:53.000
und ich mache irgendein JavaScript-File auf

00:43:53.000 --> 00:43:56.000
und das läuft im Hintergrund schon der TypeScript-Compiler

00:43:56.000 --> 00:43:57.000
und checkt meinen JavaScript-Call

00:43:57.000 --> 00:44:00.000
und versucht zu inferieren und zu verstehen,

00:44:00.000 --> 00:44:01.000
was ich schon geschrieben habe, ohne

00:44:01.000 --> 00:44:03.000
eine einzige Typ-Annotation.

00:44:04.000 --> 00:44:05.000
Und ich kriege aus dem raus schon

00:44:05.000 --> 00:44:08.000
Autocomplete und die ersten

00:44:08.000 --> 00:44:09.000
Warnings, dass vielleicht irgendwas nicht ganz

00:44:09.000 --> 00:44:12.000
rund läuft

00:44:12.000 --> 00:44:14.000
und schief geht. Das ist so viel

00:44:14.000 --> 00:44:16.000
wert, ohne dass ich eine Zeile TypeScript

00:44:16.000 --> 00:44:18.000
schreibe, wo ich mir denke, ja, das ist eigentlich

00:44:18.000 --> 00:44:19.000
eine richtig gute Idee gewesen.

00:44:20.000 --> 00:44:21.000
Ja.

00:44:21.000 --> 00:44:24.000
Da kann Python sich, glaube ich,

00:44:24.000 --> 00:44:25.000
auch noch eine Scheibe abschneiden.

00:44:25.000 --> 00:44:28.000
Da gibt es noch so ein paar Löcher.

00:44:28.000 --> 00:44:29.000
Wenn ich jetzt sage,

00:44:30.000 --> 00:44:31.000
ich installiere PyCharm oder wie auch immer,

00:44:32.000 --> 00:44:34.000
welche Idee, und die kommt schon

00:44:34.000 --> 00:44:36.000
mit einem Typinterpreter oder

00:44:36.000 --> 00:44:38.000
einem Typechecker mit, das wäre natürlich

00:44:38.000 --> 00:44:39.000
göttlich nett, dass du einfach sagst,

00:44:39.000 --> 00:44:41.000
du brauchst nicht mehr die Typernotation schreiben,

00:44:42.000 --> 00:44:44.000
aber die Idee hat irgendeinen

00:44:44.000 --> 00:44:45.000
Typechecker schon per Default drinnen.

00:44:46.000 --> 00:44:47.000
Wahrscheinlich schreiben sie ihn selbst, weil

00:44:47.000 --> 00:44:49.000
Chatprints schreiben sie irgendwie selbst.

00:44:49.000 --> 00:44:49.000
Haben sie.

00:44:49.000 --> 00:44:51.000
Dann werde ich schon.

00:44:52.000 --> 00:45:06.000
Der von Jetbrains ist aber der ist super gut Das ist einer der Gr warum man PyCharm verwendet weil die halt da die beste Typ haben Man merkt schon dass es unter Java ist

00:45:06.000 --> 00:45:08.000
Aber das können sie.

00:45:08.000 --> 00:45:09.000
Das sind sie richtig, richtig gut.

00:45:10.000 --> 00:45:11.000
Schon wieder Rust.

00:45:11.000 --> 00:45:13.000
Für Rust haben sie auch einen eigenen geschrieben.

00:45:13.000 --> 00:45:15.000
Die ganze Welt verwendet Rust Analyzer.

00:45:15.000 --> 00:45:18.000
Außer du nimmst Rust Rover von JetBrains,

00:45:18.000 --> 00:45:19.000
dann ist da ein eigener drinnen.

00:45:20.000 --> 00:45:21.000
Sie haben auch

00:45:21.000 --> 00:45:22.000
Recht damit.

00:45:22.000 --> 00:45:27.000
Also das ist halt alles richtig gut integriert in die Werkzeuge, die sie zur Verfügung stellen.

00:45:29.000 --> 00:45:44.000
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, 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.

00:45:44.000 --> 00:45:47.000
halt dann, und das ist bei Python

00:45:47.000 --> 00:45:48.000
nicht so, weil die

00:45:48.000 --> 00:45:50.000
statischen Type-Checker vor allen Dingen von den großen

00:45:50.000 --> 00:45:53.000
Gebäuden gebaut werden, halt nicht

00:45:53.000 --> 00:45:55.000
MyPy, Dropbox, ich weiß nicht, ob die

00:45:55.000 --> 00:45:57.000
immer noch da so hauptsächlich dran sind, aber dann gibt's noch

00:45:57.000 --> 00:45:58.000
einen von Google, es gibt noch Pyright,

00:45:59.000 --> 00:46:01.000
die hängen sowieso

00:46:01.000 --> 00:46:03.000
immer so ein bisschen in den Versionen hinterher,

00:46:03.000 --> 00:46:05.000
weil sie ihre Code-Basis

00:46:05.000 --> 00:46:07.000
sowieso nicht an der aktuellsten Version halten können,

00:46:07.000 --> 00:46:09.000
weil sie das gar nicht schaffen, weil das einfach zu viel Arbeit

00:46:09.000 --> 00:46:10.000
ist. Das heißt,

00:46:10.000 --> 00:46:12.000
normalerweise bei MyPy hängst du halt immer so

00:46:12.000 --> 00:46:15.000
eine Version irgendwie von dem, was die

00:46:15.000 --> 00:46:17.000
Sprache eigentlich kann, zurück, was halt

00:46:17.000 --> 00:46:18.000
auch total doof ist einfach.

00:46:19.000 --> 00:46:20.000
Du musst dich auch noch darauf einigen,

00:46:21.000 --> 00:46:23.000
welches Subset des Typsystems du jetzt

00:46:23.000 --> 00:46:23.000
verwendest.

00:46:24.000 --> 00:46:26.000
Ja, genau.

00:46:26.000 --> 00:46:28.000
Da kann ja gar nichts schief gehen.

00:46:30.000 --> 00:46:30.000
Ja,

00:46:30.000 --> 00:46:32.000
das ist ja keine Tester.

00:46:35.000 --> 00:46:37.000
Das TypeScript-Own-Management

00:46:37.000 --> 00:46:38.000
ist ja stark in der Kritik,

00:46:38.000 --> 00:46:39.000
sehr keine Frage.

00:46:39.000 --> 00:46:43.000
Also das ist einfach ein schwieriges Problem.

00:46:44.000 --> 00:46:46.000
Ja, und das ist aber einfach ein schwieriges Problem.

00:46:47.000 --> 00:46:51.000
Also ich glaube tatsächlich, dass TypeScript einfach dadurch, dass es eine jüngere Sprache ist,

00:46:51.000 --> 00:46:59.000
gewisse Fehler vermeiden konnte, die man halt vor 20 oder 25 oder 30 Jahren machen musste mit den ganzen alten Sprachen.

00:47:00.000 --> 00:47:05.000
Aber manche Sachen sind halt immer noch nicht gelöst und Version Hell gehört halt dazu.

00:47:06.000 --> 00:47:08.000
Wobei ja auch sagen, dass TypeScript ist schon historisch gewachsen.

00:47:08.000 --> 00:47:20.000
Also du merkst schon die dunklen Flecken der Vergangenheit und versuchst sie zu ignorieren. Das ist halt so. Das passiert halt. So wie Sachen verwendet werden, hast du nachher die Probleme.

00:47:20.000 --> 00:47:29.000
Ja, und das muss sich ja auch an JavaScript orientieren. Also es muss ja JavaScript-kompatibel sein und da kriegst du halt viel, sag ich mal, Historie.

00:47:30.000 --> 00:47:34.000
Ja, ein kleines bisschen Programmiersprachen-Historie mitgeliefert.

00:47:34.000 --> 00:47:35.000
Ja.

00:47:40.000 --> 00:47:42.000
Ich wollte gerade nochmal auf Java ein,

00:47:42.000 --> 00:47:43.000
wo wir das gerade hatten.

00:47:43.000 --> 00:47:44.000
Das ist leider schon ein bisschen drüber,

00:47:45.000 --> 00:47:46.000
aber davon wieder weg.

00:47:47.000 --> 00:47:49.000
Da hatte ich nämlich auch noch so eine schöne,

00:47:49.000 --> 00:47:51.000
da habe ich letztens was sehr Schönes

00:47:51.000 --> 00:47:53.000
gelesen,

00:47:55.000 --> 00:47:56.000
dass halt

00:47:56.000 --> 00:47:58.000
einer der Autoren,

00:47:58.000 --> 00:48:00.000
auch von der Sprachspezifikation

00:48:00.000 --> 00:48:02.000
von Java, hat halt

00:48:02.000 --> 00:48:04.000
irgendwann mal so geschrieben

00:48:04.000 --> 00:48:06.000
zu den Generics, also dass sie

00:48:06.000 --> 00:48:08.000
Generics eingeführt haben, also ja,

00:48:08.000 --> 00:48:10.000
das war irgendwie ein Fehler.

00:48:12.000 --> 00:48:15.000
Und dann hat er irgendwie noch,

00:48:15.000 --> 00:48:18.000
in dem Buch selber findet man auch irgendwo so eine sehr schöne

00:48:18.000 --> 00:48:20.000
Fußnote,

00:48:22.000 --> 00:48:25.000
wo halt quasi die

00:48:25.000 --> 00:48:28.000
Annotation von

00:48:28.000 --> 00:48:28.000
Inam,

00:48:29.000 --> 00:48:31.000
Inam ist auch ein Partner ein Problem, aber

00:48:31.000 --> 00:48:32.000
in Java halt auch,

00:48:32.000 --> 00:48:35.000
und Inam ist halt

00:48:35.000 --> 00:48:36.000
irgendwie definiert

00:48:36.000 --> 00:48:38.000
als, ich such grad, ob ich das hier finde, ah ja genau

00:48:38.000 --> 00:48:40.000
ist eine

00:48:40.000 --> 00:48:43.000
generische Klasse definiert als Inam

00:48:43.000 --> 00:48:45.000
Spitze Klammer T Extens Inam

00:48:45.000 --> 00:48:46.000
Spitze Klammer T Klammer zu Klammer zu

00:48:46.000 --> 00:48:49.000
also diese rekursive

00:48:49.000 --> 00:48:50.000
Definition ist halt so ein bisschen

00:48:50.000 --> 00:48:53.000
schwierig zu verstehen

00:48:53.000 --> 00:48:55.000
wir haben inzwischen aufgegeben, es zu versuchen

00:48:55.000 --> 00:48:56.000
Leuten zu erklären, es gibt irgendwie

00:48:56.000 --> 00:48:58.000
Spezialisten, die uns versichert

00:48:58.000 --> 00:49:00.000
haben, über Typtheorie

00:49:00.000 --> 00:49:03.000
uns versichert haben, dass das schon alles okay ist und kein

00:49:03.000 --> 00:49:05.000
Problem und wir sollen uns einfach nicht so viel

00:49:05.000 --> 00:49:07.000
Gedanken drüber machen, was

00:49:07.000 --> 00:49:08.000
wir sehr gerne annehmen.

00:49:11.000 --> 00:49:13.000
Das Spannende ist ja bei den Java

00:49:13.000 --> 00:49:14.000
Generics, dass die

00:49:14.000 --> 00:49:17.000
als einziges Element

00:49:17.000 --> 00:49:18.000
im Typsystem von Java

00:49:18.000 --> 00:49:20.000
keine

00:49:20.000 --> 00:49:23.000
Auswirkungen auf die Gestaltung

00:49:23.000 --> 00:49:25.000
der Laufzeituobjekte haben. Also das sind

00:49:25.000 --> 00:49:25.000
auch so,

00:49:26.000 --> 00:49:29.000
nach dem Compile-Schritt wird das einfach entfernt

00:49:29.000 --> 00:49:30.000
und nie wieder angesehen.

00:49:31.000 --> 00:49:33.000
Und das ist halt das Beeindruckende

00:49:33.000 --> 00:49:34.000
daran. Also das war halt auch so,

00:49:34.000 --> 00:49:36.000
oh shit, das brauchen wir jetzt, wir müssen das jetzt machen

00:49:36.000 --> 00:49:38.000
im Release 1.5, glaube ich war das.

00:49:38.000 --> 00:49:40.000
Und das war die einfachste und

00:49:40.000 --> 00:49:43.000
unproblematischste Art, wie wir dazu kommen.

00:49:44.000 --> 00:49:45.000
Und

00:49:45.000 --> 00:49:46.000
alle Implikationen, die das hat,

00:49:47.000 --> 00:49:48.000
die werden bis heute mitgezogen. Du kannst quasi

00:49:48.000 --> 00:49:50.000
generische Klassen nie

00:49:50.000 --> 00:49:52.000
wirklich optimieren. Geht einfach nicht.

00:49:53.000 --> 00:50:04.000
Was halt spannend ist weil die hast du halt Du hast Generics drin Deswegen werden auch oft nur in der Standardbibliothek das generische Object verwendet

00:50:04.000 --> 00:50:06.000
anstatt dass du einen generischen Typ-Parameter hast.

00:50:07.000 --> 00:50:09.000
Was ich mit Innamen sein kann, weiß ich sowieso nicht.

00:50:09.000 --> 00:50:11.000
Ich habe das gesehen bei unseren Kollegen

00:50:11.000 --> 00:50:13.000
und das ist kein Innamen.

00:50:14.000 --> 00:50:18.000
Ich finde das eigentlich jetzt ein guter Zeitpunkt,

00:50:18.000 --> 00:50:19.000
um nochmal so ein bisschen zu erklären,

00:50:20.000 --> 00:50:21.000
worum es überhaupt geht und was da alles so drin ist.

00:50:21.000 --> 00:50:23.000
Wir sind jetzt auch schon auf so einem relativ hohen Fluglevel

00:50:23.000 --> 00:50:25.000
unterwegs, aber wir haben auch

00:50:25.000 --> 00:50:27.000
viele Menschen,

00:50:27.000 --> 00:50:29.000
die uns zuhören, die vielleicht noch gar nicht wissen,

00:50:29.000 --> 00:50:31.000
was denn ein Generic überhaupt ist

00:50:31.000 --> 00:50:33.000
und vielleicht sollten wir das einmal kurz

00:50:33.000 --> 00:50:34.000
ja,

00:50:35.000 --> 00:50:38.000
jetzt kriegen sie es halt mal gesagt.

00:50:38.000 --> 00:50:38.000
Ja.

00:50:40.000 --> 00:50:42.000
Im IFCenis gibt es auch Generics

00:50:42.000 --> 00:50:42.000
in Python.

00:50:44.000 --> 00:50:44.000
Ja, genau.

00:50:46.000 --> 00:50:47.000
Wovon geht das?

00:50:48.000 --> 00:50:49.000
Ja, also das ist ja,

00:50:49.000 --> 00:50:51.000
also diese Generics in den

00:50:51.000 --> 00:50:53.000
Typ-Annotationen, das ist ja

00:50:53.000 --> 00:50:55.000
wirklich nur sehr instruktiv,

00:50:55.000 --> 00:50:56.000
nur sehr so

00:50:56.000 --> 00:50:58.000
vage gesagt,

00:50:59.000 --> 00:51:01.000
da ist die Erasure ja

00:51:01.000 --> 00:51:03.000
noch viel größer.

00:51:05.000 --> 00:51:05.000
Johannes,

00:51:06.000 --> 00:51:08.000
was ist denn bitte ein Generic?

00:51:09.000 --> 00:51:10.000
Ein

00:51:10.000 --> 00:51:11.000
Generic ist eine Spezialisierung

00:51:11.000 --> 00:51:13.000
eines Typen anhand eines

00:51:13.000 --> 00:51:15.000
anderen Typen und das klassische Beispiel ist da

00:51:15.000 --> 00:51:17.000
die Java-Liste. In Python

00:51:17.000 --> 00:51:18.000
hast du ja eine Liste, die

00:51:18.000 --> 00:51:21.000
dynamisch typisiert ist, das heißt, wenn du eine Liste

00:51:21.000 --> 00:51:23.000
hast, kannst du da eine Zahl reintun und einen String

00:51:23.000 --> 00:51:25.000
und eine

00:51:25.000 --> 00:51:27.000
komplexe Zahl und ein Objekt und noch

00:51:27.000 --> 00:51:29.000
eine Liste. Das ist immer sehr unterhaltsam,

00:51:29.000 --> 00:51:31.000
wenn ich das in den

00:51:31.000 --> 00:51:33.000
Seminaren mache, wenn ich den Leuten

00:51:33.000 --> 00:51:35.000
Programmieren beibringe, die vielleicht schon mal

00:51:35.000 --> 00:51:37.000
eine Programmiersprache gesehen haben oder die

00:51:37.000 --> 00:51:39.000
schon was davon gehört haben. Dann zeige ich hier so,

00:51:39.000 --> 00:51:41.000
jetzt kannst du da, du kannst noch eine Liste auch reintun

00:51:41.000 --> 00:51:43.000
oder Dictionary kannst du auch einfach in deine Liste

00:51:43.000 --> 00:51:44.000
reintun. Und

00:51:44.000 --> 00:51:47.000
in Java geht das nicht. In Java hat jede

00:51:47.000 --> 00:51:49.000
Liste einen Typen. Das heißt, du kannst,

00:51:50.000 --> 00:51:51.000
wenn du einfach nur List

00:51:51.000 --> 00:51:52.000
sagst, dann meinst du List von Object.

00:51:53.000 --> 00:51:54.000
Das heißt, alles, was du da reintun kannst, ist Object.

00:51:55.000 --> 00:51:57.000
Aber du kannst

00:51:57.000 --> 00:51:59.000
diese Liste spezieller

00:51:59.000 --> 00:52:00.000
gestalten, indem du eben diesen

00:52:00.000 --> 00:52:03.000
Generic-Mechanismus verwendest und sagst,

00:52:03.000 --> 00:52:04.000
du hast jetzt nicht eine Liste von Object, sondern

00:52:04.000 --> 00:52:06.000
du hast eine Liste von String.

00:52:06.000 --> 00:52:09.000
Das heißt, der Compiler weiß an bestimmten

00:52:09.000 --> 00:52:11.000
Stellen, dass dieser Typ, den du da

00:52:11.000 --> 00:52:12.000
hingeschrieben hast, der vorher vielleicht nur ein

00:52:12.000 --> 00:52:13.000
Platzhalter war,

00:52:14.000 --> 00:52:17.000
in TypeScript verwendet man dann oft T oder K oder V,

00:52:17.000 --> 00:52:19.000
das ist auch in Stefans Buch

00:52:19.000 --> 00:52:20.000
kommt es mehrmals vor,

00:52:21.000 --> 00:52:28.000
dass du dann eben zu einem bestimmten Zeitpunkt diesen generischen Typen ersetzt durch einen konkreten Typen und sagst,

00:52:28.000 --> 00:52:33.000
okay, ich habe jetzt hier nicht eine Liste von Objects, sondern ich habe ganz klar eine Liste von String.

00:52:33.000 --> 00:52:40.000
Und dann kann der Compiler oder eben das Typsystem überprüfen, dass du da tatsächlich lauter Strings drin hast.

00:52:41.000 --> 00:52:47.000
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.

00:52:47.000 --> 00:52:50.000
und das hat gewisse Vorteile, zum Beispiel

00:52:50.000 --> 00:52:51.000
wenn du da ein Objekt rausholst,

00:52:52.000 --> 00:52:54.000
kriegst du dann halt eben nicht nur ein generisches

00:52:54.000 --> 00:52:56.000
Object zurück, sondern du kriegst dann tatsächlich

00:52:56.000 --> 00:52:57.000
einen String zurück.

00:52:58.000 --> 00:53:00.000
Das ist der große Vorteil, den Java davon hat,

00:53:00.000 --> 00:53:01.000
dass du diese Accessor-Methoden hast,

00:53:02.000 --> 00:53:03.000
die dir die spezifischen Sachen

00:53:03.000 --> 00:53:05.000
rausgeben.

00:53:06.000 --> 00:53:08.000
War das korrekt erklärt, Stefan?

00:53:09.000 --> 00:53:09.000
Ist cool.

00:53:09.000 --> 00:53:10.000
Super, genau das.

00:53:11.000 --> 00:53:12.000
Gott, Experte.

00:53:13.000 --> 00:53:14.000
Ich sage ja nicht, ich bin nie Experte, ich bin einfach nur

00:53:14.000 --> 00:53:16.000
aufgehoben und schreibe den ganzen Mist auf.

00:53:17.000 --> 00:53:18.000
Ja gut, aber das macht dich zum Experten.

00:53:19.000 --> 00:53:20.000
Aber nein, das beschreibst du ziemlich gut.

00:53:20.000 --> 00:53:23.000
Also du kannst mit Typ-Parametern

00:53:23.000 --> 00:53:27.000
dir die Entscheidung auf den tatsächlichen Typen

00:53:27.000 --> 00:53:28.000
für später aufheben.

00:53:28.000 --> 00:53:29.000
Das ist das, was dort passiert.

00:53:30.000 --> 00:53:31.000
Und eben so sagst du,

00:53:31.000 --> 00:53:33.000
dann wird das halt eine Array-List von String

00:53:33.000 --> 00:53:35.000
oder eine Array-List von Integer

00:53:35.000 --> 00:53:38.000
und du substituierst diesen Typ-Parameter

00:53:38.000 --> 00:53:39.000
mit einem konkreten Typen

00:53:39.000 --> 00:53:43.000
und kriegst nachher auch solche konkreten Typen

00:53:43.000 --> 00:53:44.000
wieder retour.

00:53:44.000 --> 00:53:45.000
In manchen Programmiersprachen

00:53:45.000 --> 00:53:47.000
kannst du dann auch noch so Dinge wie

00:53:47.000 --> 00:53:49.000
Constraints oder Bounds angeben,

00:53:50.000 --> 00:53:51.000
wo du eben sagst, hey, du hast dort

00:53:51.000 --> 00:53:53.000
jetzt einen beliebigen Typparameter, ja,

00:53:54.000 --> 00:53:55.000
aber er muss einem gewissen

00:53:55.000 --> 00:53:57.000
Subtypen entsprechen. Das heißt, er muss

00:53:57.000 --> 00:53:59.000
eine gewisse Funktionalität zur Verfügung haben

00:53:59.000 --> 00:54:00.000
oder muss

00:54:00.000 --> 00:54:03.000
also TypeScript

00:54:03.000 --> 00:54:06.000
ist ja strukturell

00:54:06.000 --> 00:54:07.000
typisiert, was bedeutet,

00:54:08.000 --> 00:54:09.000
dass du einfach sagst, hey, solange die Methoden

00:54:09.000 --> 00:54:12.000
dort sind und solange die Properties

00:54:12.000 --> 00:54:13.000
dort sind, passt schon, muss nicht

00:54:13.000 --> 00:54:16.000
den gleichen Namen haben, muss nicht in irgendeiner Hierarchie sein,

00:54:16.000 --> 00:54:18.000
sondern Hauptsache, schaut irgendwie

00:54:18.000 --> 00:54:19.000
so aus, wie das eine, was

00:54:19.000 --> 00:54:22.000
ich da erwarten würde. Und dann haut das schon hin.

00:54:22.000 --> 00:54:23.000
Und dann kriegst du halt

00:54:23.000 --> 00:54:25.000
zum einen die Sicherheit, dass du nicht

00:54:25.000 --> 00:54:28.000
irgendwelche Typen reingibst, die nicht damit funktionieren

00:54:28.000 --> 00:54:29.000
würden.

00:54:30.000 --> 00:54:31.000
Und zum anderen

00:54:31.000 --> 00:54:33.000
kriegst du halt noch mehr Informationen

00:54:33.000 --> 00:54:36.000
über deinen Typ noch heraus, wenn du ihn dann vermeidest.

00:54:36.000 --> 00:54:38.000
Wie macht man das denn in Python? Protokolle?

00:54:38.000 --> 00:54:40.000
Doch, das ist in Python, das ist halt

00:54:40.000 --> 00:54:42.000
drei Achtung Gründer auch so, oder kann man

00:54:42.000 --> 00:54:43.000
das so machen? Man kann auch nominal

00:54:43.000 --> 00:54:45.000
typisiert das Ganze machen, aber

00:54:45.000 --> 00:54:47.000
da geht das jetzt auch, genau, mit Typing

00:54:47.000 --> 00:54:48.000
Protocols

00:54:48.000 --> 00:54:51.000
geht das auch.

00:54:51.000 --> 00:54:53.000
Ja, genau, und dann...

00:54:53.000 --> 00:55:04.000
Habt ihr das schon mal irgendwo gesehen Ja ich verwende das Bevor es jetzt Ja ja Also ich finde das eine gro Idee aber ich habe es noch nie irgendwo verwendet gesehen Ja ja doch Also ich kenne es

00:55:04.000 --> 00:55:05.000
auch vor allen Dingen aus dem

00:55:05.000 --> 00:55:06.000
Fluent Python

00:55:06.000 --> 00:55:10.000
Buch von Luciano

00:55:10.000 --> 00:55:10.000
Ramallo.

00:55:12.000 --> 00:55:14.000
Und der hat sich auch

00:55:14.000 --> 00:55:15.000
mit diesem Typisierungsthema

00:55:15.000 --> 00:55:17.000
stark beschäftigt und hat dann diverse Fehler

00:55:17.000 --> 00:55:19.000
in der TypeShed

00:55:19.000 --> 00:55:22.000
Repository, wo halt

00:55:22.000 --> 00:55:23.000
die ganzen, wo auch die Standardbibliothek von

00:55:23.000 --> 00:55:26.000
Python genau

00:55:26.000 --> 00:55:28.000
annotiert ist, hat er

00:55:28.000 --> 00:55:30.000
da gefunden und viele

00:55:30.000 --> 00:55:31.000
davon konnte er fixen mit

00:55:31.000 --> 00:55:33.000
diesem Structural Typing

00:55:33.000 --> 00:55:35.000
Ansatz. Also

00:55:35.000 --> 00:55:37.000
Fehler im Sinne von halt

00:55:37.000 --> 00:55:39.000
die Annotationen waren halt

00:55:39.000 --> 00:55:42.000
False Positives oder halt

00:55:42.000 --> 00:55:44.000
False Negatives möglich. Auch sehr

00:55:44.000 --> 00:55:46.000
interessant, wenn man sich halt anguckt,

00:55:46.000 --> 00:55:47.000
welche Fehler sind häufiger?

00:55:48.000 --> 00:55:50.000
False Positives sind

00:55:50.000 --> 00:55:52.000
viel, viel häufiger bei Typ-Annotationen

00:55:52.000 --> 00:55:53.000
als false negatives. Also in

00:55:53.000 --> 00:55:55.000
der Python-Standard-Bibliothek waren es

00:55:55.000 --> 00:55:56.000
irgendwie achtmal so häufig.

00:55:57.000 --> 00:55:59.000
Was halt auch ein Hinweis darauf ist, dass es halt

00:55:59.000 --> 00:56:01.000
für Leute wichtiger ist, dass halt die,

00:56:02.000 --> 00:56:03.000
also false positive heißt,

00:56:04.000 --> 00:56:05.000
eine Annotation hat gesagt, nee,

00:56:05.000 --> 00:56:07.000
du kommst hier nicht rein, das ist irgendwie,

00:56:07.000 --> 00:56:09.000
du bist nicht der richtige Typ.

00:56:09.000 --> 00:56:11.000
Dein Typ ist hier nicht gefragt.

00:56:14.000 --> 00:56:15.000
Sozusagen, obwohl es

00:56:15.000 --> 00:56:17.000
eigentlich doch okay gewesen wäre.

00:56:18.000 --> 00:56:19.000
Und also offenbar

00:56:19.000 --> 00:56:23.000
es ist halt irgendwie so mehr opportun

00:56:23.000 --> 00:56:25.000
irgendwie auf der Seite von strikter

00:56:25.000 --> 00:56:27.000
zu sein, zu irren, als umgekehrt.

00:56:29.000 --> 00:56:30.000
Was ja auch so ein bisschen vielleicht

00:56:30.000 --> 00:56:32.000
damit zusammenhängt, welche Leute das

00:56:32.000 --> 00:56:35.000
vor allen Dingen gut ist, nämlich die, die halt versuchen

00:56:35.000 --> 00:56:37.000
wollen, möglichst viel da draußen zu halten

00:56:37.000 --> 00:56:39.000
und wenn sie ein bisschen zu viel draußen halten, ist es besser

00:56:39.000 --> 00:56:41.000
als was durchzulassen, was halt dann

00:56:41.000 --> 00:56:42.000
irgendwie knallt zur Laufzeit.

00:56:43.000 --> 00:56:44.000
Das wäre dann voll snaggert.

00:56:45.000 --> 00:56:47.000
Ja, genau.

00:56:47.000 --> 00:56:48.000
Und ja,

00:56:48.000 --> 00:56:50.000
der hat das

00:56:50.000 --> 00:56:52.000
also lange erklärt

00:56:52.000 --> 00:56:55.000
in dem Buch und da habe ich das halt quasi

00:56:55.000 --> 00:56:56.000
her und ja, ich finde das

00:56:56.000 --> 00:56:58.000
eigentlich sehr nett, weil damit kann man im Grunde genau das gleiche

00:56:58.000 --> 00:57:00.000
machen wie ein TypeScript mit diesen Intersection

00:57:00.000 --> 00:57:02.000
und Union Types,

00:57:03.000 --> 00:57:05.000
was ja auch irgendwie so, das ist halt so

00:57:05.000 --> 00:57:06.000
sehr cool eigentlich, dass das

00:57:06.000 --> 00:57:09.000
geht und das geht halt

00:57:09.000 --> 00:57:10.000
wenn man jetzt so mit

00:57:10.000 --> 00:57:12.000
Abstract Base Classes das Ganze macht und Nominal

00:57:12.000 --> 00:57:14.000
geht das halt nicht so richtig

00:57:14.000 --> 00:57:16.000
und aber

00:57:16.000 --> 00:57:18.000
Das Problem ist, wenn es zu Nominal arbeitet,

00:57:18.000 --> 00:57:21.000
dass du auf dem Schlag eine Hierarchie aufbaust,

00:57:21.000 --> 00:57:23.000
auch wenn die implizit ist durch die Basistypen,

00:57:23.000 --> 00:57:24.000
die du definierst.

00:57:24.000 --> 00:57:27.000
Und das kannst du sehr schön und elegant umschiffen,

00:57:27.000 --> 00:57:29.000
indem du sagst, hey, alles, was ich erwarte,

00:57:29.000 --> 00:57:31.000
ist einfach nur, dass das Ding so ausschaut

00:57:31.000 --> 00:57:33.000
oder diese Werte und Eigenschaften hat,

00:57:34.000 --> 00:57:36.000
die ich an dieser Stelle erwarte.

00:57:37.000 --> 00:57:40.000
Methodennamen, Rückgabewerte, Propertytypen etc.

00:57:42.000 --> 00:57:45.000
Und ich sage mal, ein Programmiersprache wie JavaScript

00:57:45.000 --> 00:57:49.000
wäre gar nicht anders zu typisieren gewesen

00:57:49.000 --> 00:57:53.000
oder es wäre gar nicht möglich gewesen, die anders zu typisieren, als wie mit einem strukturellen Typsystem,

00:57:54.000 --> 00:57:57.000
weil sonst praktisch kein Code mehr funktioniert hätte, den du irgendwie geschrieben hast.

00:57:58.000 --> 00:58:01.000
Und das war eben auch so ein Designprinzip von TypeScript, dass sie sagen, hey, wir wollen

00:58:01.000 --> 00:58:05.000
bestehenden JavaScript-Code unterstützen und mögliche Fehler herausfinden

00:58:05.000 --> 00:58:08.000
und nicht einfach nur aufgrund von einem arbitrer

00:58:08.000 --> 00:58:13.000
geschaffenen Hierarchiekonstrukt sagen, das passt oder passt nicht.

00:58:13.000 --> 00:58:16.000
und ich glaube,

00:58:16.000 --> 00:58:18.000
es kann man gut vorstellen, dass das Python auch

00:58:18.000 --> 00:58:18.000
stark hilft.

00:58:20.000 --> 00:58:20.000
Definitiv.

00:58:21.000 --> 00:58:22.000
Ja, das ist jetzt also seitdem,

00:58:23.000 --> 00:58:24.000
ich meine, ist das auch, glaube ich,

00:58:25.000 --> 00:58:27.000
in Go ist das ja auch so,

00:58:27.000 --> 00:58:29.000
die Interfaces in Go verhalten sich im Grunde auch so.

00:58:30.000 --> 00:58:31.000
Genau, du implementierst

00:58:31.000 --> 00:58:34.000
implizit Interfaces, wenn die Methodensignatur

00:58:34.000 --> 00:58:35.000
gleich ist, genau.

00:58:35.000 --> 00:58:37.000
Dann bist du kompatibel zum Interface.

00:58:38.000 --> 00:58:38.000
Ja.

00:58:39.000 --> 00:58:40.000
Ja, und

00:58:40.000 --> 00:58:42.000
ich verwende das tatsächlich.

00:58:42.000 --> 00:58:44.000
Ich glaube auch, das ist eigentlich sozusagen das,

00:58:44.000 --> 00:58:45.000
wo es dann anfängt, Spaß zu machen.

00:58:46.000 --> 00:58:48.000
Weil ehrlich gesagt, mit den Hierarchien,

00:58:48.000 --> 00:58:50.000
Klassenhierarchien und so, das ist nicht so

00:58:50.000 --> 00:58:51.000
meine Vorstellung von Spaß.

00:58:51.000 --> 00:58:52.000
Ja, also,

00:58:52.000 --> 00:58:58.000
du hast ganz recht, Johannes.

00:58:59.000 --> 00:59:00.000
Ich glaube, es war Johannes.

00:59:01.000 --> 00:59:03.000
Ja, genau, das ist das, was natürlich passiert.

00:59:03.000 --> 00:59:04.000
Du hast Klassen und dann hast du Hierarchien davon

00:59:04.000 --> 00:59:06.000
und dann benutzt du die und fertig.

00:59:06.000 --> 00:59:08.000
Das ist dem Konstrukt zu schulden.

00:59:09.000 --> 00:59:11.000
Und der Konstrukt hat auch nichts dafür.

00:59:11.000 --> 00:59:12.000
Das ist halt einfach so.

00:59:13.000 --> 00:59:14.000
Nee, und das liegt halt auch nahe.

00:59:14.000 --> 00:59:16.000
Du hast schon diese Hierarchie und dann benutzt

00:59:16.000 --> 00:59:18.000
du sie halt auch weiter. Du hast schon die Struktur, also nehmen wir sie.

00:59:19.000 --> 00:59:19.000
Ja.

00:59:21.000 --> 00:59:22.000
Ja, ja. Aber das ist dann eben das

00:59:22.000 --> 00:59:24.000
Problem, worauf du dann triffst.

00:59:24.000 --> 00:59:26.000
Du kommst an eine Stelle, wo du weißt,

00:59:27.000 --> 00:59:28.000
hier muss ich jetzt eigentlich nur addieren,

00:59:28.000 --> 00:59:30.000
aber der Typ, den du verlangen musst, ist halt

00:59:30.000 --> 00:59:32.000
irgendein ganz Wilder oder ein ganz

00:59:32.000 --> 00:59:34.000
Abgefahrener oder irgendeiner, der wo ganz

00:59:34.000 --> 00:59:35.000
anders in der Hierarchie drin ist.

00:59:37.000 --> 00:59:38.000
Was mir sehr

00:59:38.000 --> 00:59:40.000
gut gefällt am

00:59:40.000 --> 00:59:42.000
Python-Typ-System, was ich gesehen habe, nur durchs

00:59:42.000 --> 00:59:45.000
drüberfliegen, ist dieses New-Type-

00:59:45.000 --> 00:59:46.000
Konstrukt, wo du sagen kannst, hey, es gibt schon

00:59:46.000 --> 00:59:48.000
einen bestehenden Typen und

00:59:48.000 --> 00:59:50.000
der ist vielleicht sehr, sehr freigiebig, der ist vielleicht

00:59:50.000 --> 00:59:52.000
ein Integer-String oder was auch immer, aber da kannst du ihm

00:59:52.000 --> 00:59:54.000
noch dieses eine Label verschaffen, damit du jetzt

00:59:54.000 --> 00:59:56.000
nicht irgendwelche unterschiedlichen Integer-Werte

00:59:56.000 --> 00:59:58.000
durcheinander kriegst oder irgendwelche Objektwerte,

00:59:58.000 --> 00:59:58.000
die...

00:59:58.001 --> 00:59:59.000
die ähnlich sind, durcheinander kriegst.

01:00:00.000 --> 01:00:03.000
Weil strukturelle Typsysteme funktionieren halt immer bis zu dem Grad,

01:00:03.000 --> 01:00:06.000
wo du sagen musst, hey, aber dieses eine Ding will ich da jetzt nicht herinnen haben,

01:00:06.000 --> 01:00:10.000
weil ich erwarte doch etwas anderes und kann das durch das Typsystem nicht so ausdrücken.

01:00:11.000 --> 01:00:13.000
Mach das Newtype, dann wird es explizit und dann kannst du genau sagen,

01:00:13.000 --> 01:00:17.000
hey, an dieser Stelle erwartest du etwas, was so ausschaut,

01:00:17.000 --> 01:00:19.000
aber es muss doch etwas anderes sein.

01:00:19.000 --> 01:00:22.000
Und das finde ich eigentlich ganz brauchbar.

01:00:22.000 --> 01:00:26.000
Das ist, genau, das benutze ich genau für diesen Use Case,

01:00:26.000 --> 01:00:26.000
dass man halt

01:00:26.000 --> 01:00:29.000
oft quasi sowas

01:00:29.000 --> 01:00:32.000
zum Beispiel Integer möchte man

01:00:32.000 --> 01:00:34.000
einschränken von der Range, aber das kann man im Typsystem

01:00:34.000 --> 01:00:36.000
nicht so richtig ausdrücken und ich finde, dann reicht

01:00:36.000 --> 01:00:38.000
oft schon, um den gleichen Effekt zu haben,

01:00:38.000 --> 01:00:40.000
im Newtype einzuführen, also wo ich

01:00:40.000 --> 01:00:42.000
das dann halt zum Beispiel aktuell brauche, ist halt

01:00:42.000 --> 01:00:44.000
ich habe halt ein Jahr und ich weiß, dieses Jahr

01:00:44.000 --> 01:00:45.000
ist halt nur von 2025 bis

01:00:45.000 --> 01:00:47.000
2040 oder irgendwie sowas

01:00:47.000 --> 01:00:48.000
und

01:00:48.000 --> 01:00:51.000
mir reicht im Grunde, wenn

01:00:51.000 --> 01:00:52.000
ich

01:00:52.000 --> 01:00:55.000
mache das gar nicht über das Typsystem, dass diese Range dann

01:00:55.000 --> 01:00:57.000
sozusagen abgesichert wird. Aber allein,

01:00:57.000 --> 01:00:59.000
dadurch, dass ich sage, ich definiere

01:00:59.000 --> 01:01:01.000
den NewTypeYear,

01:01:02.000 --> 01:01:03.000
der halt eigentlich ein Int ist,

01:01:03.000 --> 01:01:04.000
kann mir der TypeChecker sagen,

01:01:05.000 --> 01:01:07.000
wenn ich irgendwie mal ein anderes Int da

01:01:07.000 --> 01:01:09.000
reingesteckt habe, was ich nicht mal als Ja

01:01:09.000 --> 01:01:10.000
irgendwo anders deklariert habe,

01:01:11.000 --> 01:01:13.000
und kriege dann sozusagen den Effekt, dass wenn da irgendjemand

01:01:13.000 --> 01:01:15.000
irgendwas reinsteckt, was kein Ja ist, dann

01:01:15.000 --> 01:01:17.000
gibt es halt auch, sagt der

01:01:17.000 --> 01:01:19.000
TypeChecker halt schon, okay, nee, das sieht

01:01:19.000 --> 01:01:21.000
nicht gut aus. Und so

01:01:21.000 --> 01:01:23.000
kann man sich halt das sozusagen so ein bisschen

01:01:23.000 --> 01:01:26.000
herbeiemulieren, dass man

01:01:26.000 --> 01:01:28.000
irgendwie damit auch überprüft, ob das

01:01:28.000 --> 01:01:30.000
inhaltlich Sinn macht.

01:01:31.000 --> 01:01:33.000
Aber noch cooler wäre es natürlich,

01:01:33.000 --> 01:01:34.000
wenn du auch die Werte angeben könntest.

01:01:35.000 --> 01:01:36.000
Entschuldigung, Stefan.

01:01:37.000 --> 01:01:37.000
Weißt du?

01:01:39.000 --> 01:01:39.000
Ja.

01:01:40.000 --> 01:01:42.000
Also gerade mit dem, also

01:01:42.000 --> 01:01:44.000
in TypeScript kannst du das ein bisschen. Du kannst

01:01:44.000 --> 01:01:46.000
teilweise Werte

01:01:46.000 --> 01:01:48.000
oder geringere Wertbereiche

01:01:48.000 --> 01:01:50.000
definieren. Also in TypeScript ist das

01:01:50.000 --> 01:01:52.000
Spannende, wie in jedem Typsystem,

01:01:52.000 --> 01:01:59.000
Du hast Wertemengen und du definierst ja nur, ob dieser eine Wert, den du hast, jetzt in diese Menge passt oder nicht.

01:02:00.000 --> 01:02:05.000
Das sind sehr große Mengen zum Teil, String, Number oder alle Objects.

01:02:05.000 --> 01:02:15.000
Zum Teil sind sie halt auf deine Objekttypen heruntergebrochen, wo du sagst, diese Kombination an Properties, die gewisse Typen haben, erlaubst du dort oder nicht.

01:02:15.000 --> 01:02:21.000
Du kannst aber auch sagen, hey, nicht dieser einzige oder einzelne konkrete Wert,

01:02:22.000 --> 01:02:27.000
die Zahl 1, der String Stefan, was auch immer, kann auch als Typ gelten.

01:02:27.000 --> 01:02:34.000
Das heißt, du kannst einen Wert haben, wo du sagst, alles, was diese Variable annehmen darf, ist der Wert 1.

01:02:35.000 --> 01:02:40.000
Und das klingt am Anfang doof, weil was machst du mit einer Variable, die nur 1 sein kann?

01:02:40.000 --> 01:02:41.000
Du kannst es schenken.

01:02:42.000 --> 01:02:46.000
Aber du kannst noch diese Literal-Types oder Value-Types,

01:02:46.000 --> 01:02:49.000
wie es du benannt hast, Johannes, kombinieren mit anderen Value-Types

01:02:49.000 --> 01:02:56.000
und kannst dann zum Beispiel alle validen Augenzahlen eines Würfels darstellen.

01:02:56.000 --> 01:02:58.000
Eins oder zwei oder drei oder vier oder fünf oder sechs.

01:02:59.000 --> 01:03:03.000
Also damit hast du schon einen sehr engen Wertebereich definiert

01:03:03.000 --> 01:03:08.000
und weißt noch aus, wenn ein Wert da reinkommt,

01:03:08.000 --> 01:03:12.000
dann hat er garantiert eine dieser sechs Zahlen.

01:03:14.000 --> 01:03:16.000
Und das ist spannend, das kannst du auch mit Strings machen.

01:03:17.000 --> 01:03:21.000
Und was halt dann wirklich elegant ist, ist, dass du zum Beispiel Strings mit gewissen Pattern definieren kannst.

01:03:21.000 --> 01:03:25.000
Du kannst sagen, hey, du erlaubst alle Strings, die mit ON anfangen,

01:03:26.000 --> 01:03:32.000
weil du gerade dein Eventsystem implementierst und du hast halt ON-Click, ON-Key-Down, ON-Key-Press, was auch immer.

01:03:32.000 --> 01:03:58.000
Das heißt, es muss mit on anfangen und nachher muss der erste Buchstabe unbedingt ein Großbuchstabe sein. Solche Strings akzeptierst du, andere akzeptierst du nicht. Da kannst du wirklich sehr elegant Wertebereiche definieren, mit denen du korrekte Werte angibst, mit denen du auch über deine Werte diverse Aussagen treffen kannst, die dir nachher helfen, die aber jetzt nicht so übermäßig komplex sind.

01:03:58.000 --> 01:04:04.000
Dass du jetzt sagst, hey, das ist jetzt viel zu viel Aufwand, das zu definieren.

01:04:05.000 --> 01:04:09.000
Mein Lieblingsbeispiel ist immer noch HTTP-Methoden,

01:04:10.000 --> 01:04:14.000
Get, Post, Delete, was auch immer, oder HTTP-Error-Codes.

01:04:15.000 --> 01:04:19.000
Da gibt es 70 um den Dreh.

01:04:20.000 --> 01:04:25.000
Ich weiß jetzt nicht, ob es 201 gibt, ob es 217 noch gibt, weiß ich nicht.

01:04:26.000 --> 01:04:28.000
Das kann mir dieser Union-Typ sehr, sehr schön sagen.

01:04:28.000 --> 01:04:30.000
Und dann bin ich mir sicher,

01:04:30.000 --> 01:04:31.000
dass ich den richtigen

01:04:31.000 --> 01:04:34.000
HTTP-Status-Code meiner Response schicke

01:04:34.000 --> 01:04:36.000
und brauche

01:04:36.000 --> 01:04:38.000
nicht großartig überlegen, ob ich

01:04:38.000 --> 01:04:39.000
noch im richtigen Wertebereich bin oder nicht.

01:04:40.000 --> 01:04:42.000
Ich muss mich einmal

01:04:42.000 --> 01:04:44.000
korrigieren. Ich habe eben nachgelesen, Value-Types

01:04:44.000 --> 01:04:44.000
ist nicht das richtige Wort.

01:04:45.000 --> 01:04:47.000
Das bezieht sich auch auf etwas anderes.

01:04:48.000 --> 01:04:50.000
Das wird als Abgrenzung

01:04:50.000 --> 01:04:51.000
zum Reference-Type verwendet.

01:04:52.000 --> 01:05:04.000
Also ob man einen Wert oder eine Referenz hat Aber das Konzept das hast du gerade sehr sch erkl Vielen Dank Stefan Das ist auch in Kapitel 4 beschrieben von meinem Buch und da bist du ja noch nicht

01:05:05.000 --> 01:05:07.000
Das haben wir vorhin schon festgestellt.

01:05:07.000 --> 01:05:08.000
Ich habe noch nicht weit genug gelesen.

01:05:09.000 --> 01:05:10.000
Aber ich habe es jetzt wieder rausgeholt

01:05:10.000 --> 01:05:12.000
und jetzt lege ich es mir

01:05:12.000 --> 01:05:14.000
unter das Kopfkissen und werde das

01:05:14.000 --> 01:05:15.000
per Diffusion aufnehmen.

01:05:15.000 --> 01:05:18.000
So habe ich die Matura geschafft

01:05:18.000 --> 01:05:21.000
mit dem Mathematikbuch unter dem Kopfkissen.

01:05:21.000 --> 01:05:22.000
Funktioniert.

01:05:22.000 --> 01:05:25.000
Ja, ich finde, wir müssen noch ein bisschen

01:05:25.000 --> 01:05:27.000
darüber reden, wie man das so in Python

01:05:27.000 --> 01:05:28.000
dann machen kann noch und wie man das

01:05:28.000 --> 01:05:31.000
Typing-Modul vielleicht noch so ein bisschen benutzt.

01:05:31.000 --> 01:05:33.000
Wir hatten jetzt ein Newtype, was

01:05:33.000 --> 01:05:34.000
irgendwie ganz cool ist. Wir hatten die Generics.

01:05:35.000 --> 01:05:37.000
Ja, also Generics, achso, genau.

01:05:37.000 --> 01:05:38.000
Wo wir dann schon mal, da habe ich nämlich jetzt heute

01:05:38.000 --> 01:05:40.000
alles gehabt, als ich versucht,

01:05:40.000 --> 01:05:42.000
da dachte ich mir so,

01:05:43.000 --> 01:05:45.000
oh mein Gott, wenn, hoffentlich fragt das keiner, deswegen frage ich

01:05:45.000 --> 01:05:47.000
das jetzt mal, kann mir

01:05:47.000 --> 01:05:49.000
einer vielleicht erklären, was der Unterschied zwischen

01:05:49.000 --> 01:05:50.000
Co-Variant, Kontra-Variant und In-Variant

01:05:50.000 --> 01:05:53.000
und so ist, weil das kann man nämlich auch mit angeben

01:05:53.000 --> 01:05:54.000
und ich dachte mir so, okay, ich kann es ja angeben,

01:05:54.000 --> 01:05:56.000
aber was bedeutet das eigentlich?

01:05:56.000 --> 01:05:57.000
Und was macht dann Bound und so?

01:06:00.000 --> 01:06:01.000
Ich kann es aus einer

01:06:01.000 --> 01:06:03.000
Typtheorie sagen, was Co- und Contra-Variant ist.

01:06:03.000 --> 01:06:04.000
Ich weiß aber nicht, ob das so auf Python

01:06:04.000 --> 01:06:05.000
auch zutrifft.

01:06:06.000 --> 01:06:08.000
Aber ich versuche es jetzt mal so

01:06:08.000 --> 01:06:10.000
zu erklären. Co-Variant ist,

01:06:11.000 --> 01:06:11.000
wenn du

01:06:11.000 --> 01:06:14.000
Schnell die Petit fragen.

01:06:16.000 --> 01:06:16.000
Nein, es ist

01:06:16.000 --> 01:06:18.000
irrsinnig schwierig zu erklären. Lass mich kurz

01:06:18.000 --> 01:06:20.000
mein zweites Buch aufmachen, weil da wäre Zeichnung.

01:06:20.000 --> 01:06:21.000
Ja.

01:06:23.000 --> 01:06:27.000
Also bevor ich jetzt allgemeine Beschreibungen erkläre, sage ich es lieber einmal so.

01:06:28.000 --> 01:06:34.000
In einer Kovariantenbeziehung hast du zum Beispiel einen Typ, der ist String oder Number.

01:06:35.000 --> 01:06:42.000
Was bedeutet, dass wenn du einen Wert hast, der Number ist, dann kannst du dir auf jeden Fall auf diesen einen Typen zuweisen, der String oder Number sein kann.

01:06:42.000 --> 01:06:50.000
Das heißt, je enger dieser Wertebereich wird, hat keinen Effekt drauf, kannst du weiterhin darauf zuweisen.

01:06:50.000 --> 01:07:12.000
Der Kontravariant ist genau umgekehrt. Du kannst zum Beispiel jetzt nicht eine Funktion, die als ersten Parameter String oder Number oder einen Funktionstypen, der als ersten Parameter String oder Number erwartet, kannst du jetzt nicht eine echte Funktion zuweisen, die nur String erwartet, weil ja der Fall, dass auch eine Number als Parameter sein kann, nicht dadurch abgedeckt wird.

01:07:12.000 --> 01:07:37.000
Das heißt, du hast der Typ zwar auch ein Subtyp, der Parametertyp ist ein Subtyp vom anderen, aber nachdem der in einer Funktion steht, sind die nicht zueinander kompatibel, sondern nur umgekehrt. Das heißt, du kannst einen Funktionstypen definieren, der als ersten Parameter eine Number angibt, was bedeutet, dass du auch Funktionen zuweisen kannst, die String oder Number erwarten, weil eben dieser eine Fall abgedeckt ist. Und das ist der Unterschied zwischen Kovarianz und Kontrovarianz.

01:07:37.000 --> 01:07:40.000
brauchst du eigentlich nie, macht halt irgendwelche komischen Fehlermeldungen,

01:07:40.000 --> 01:07:41.000
wenn du irgendwelche Sachen zuweisen willst, die dann

01:07:41.000 --> 01:07:42.000
nicht so funktionieren.

01:07:44.000 --> 01:07:46.000
Ist aber, glaube ich, in der Typtheorie

01:07:46.000 --> 01:07:48.000
die korrekte Beschreibung.

01:07:49.000 --> 01:07:50.000
Ist nicht kompliziert, ich möchte euch

01:07:50.000 --> 01:07:52.000
da für die Shownotes eine Grafik zur Verfügung

01:07:52.000 --> 01:07:53.000
stellen, die das wunderschön erklärt.

01:07:54.000 --> 01:07:55.000
Und da suche ich mir den Link

01:07:55.000 --> 01:07:57.000
jetzt wirklich raus aus meinem Buch, weil das habe ich genau

01:07:57.000 --> 01:07:59.000
aus dem Grund habe ich es da rein.

01:08:00.000 --> 01:08:01.000
Weil das sind die Sachen, die merke ich mir selber nie genau.

01:08:02.000 --> 01:08:03.000
Das ist was man einmal nachlesen muss.

01:08:03.000 --> 01:08:05.000
Also in welche Richtung kann man was irgendwie doch

01:08:05.000 --> 01:08:07.000
voneinander erben, wenn ich das richtig verstehe?

01:08:07.000 --> 01:08:09.000
Und das allgemeiner annotieren?

01:08:09.000 --> 01:08:09.000
Generisieren.

01:08:11.000 --> 01:08:12.000
Also ich habe es jetzt hier auch gerade,

01:08:13.000 --> 01:08:15.000
wenn jemand anders spricht, kann ich ja googeln.

01:08:17.000 --> 01:08:19.000
Also so wie ich das jetzt hier verstehe,

01:08:19.000 --> 01:08:21.000
das bezieht sich direkt auf Python

01:08:21.000 --> 01:08:22.000
hier und

01:08:22.000 --> 01:08:25.000
Qualitätsquelle Stack Overflow

01:08:25.000 --> 01:08:26.000
kann man ja auch verlinken.

01:08:28.000 --> 01:08:29.000
Es wird hier so erklärt,

01:08:29.000 --> 01:08:31.000
du hast zwei Klassen, Basisklasse

01:08:31.000 --> 01:08:32.000
und eine abgeleitete Klasse.

01:08:32.000 --> 01:08:33.000
Die derived.

01:08:33.000 --> 01:08:57.000
Genau. B und D, also Basisklasse und abgeleitete Klasse. Und du hast irgendeine generische Typenliste mit irgendeinem Typen drin. Und jetzt ist die Frage, wenn du eine Liste hast, die den Typen B hat, also den Basistypen, kannst du die dann da verwenden, wo du eine Liste vom Typen D erwartest, also eine abgeleitete Klasse? Oder ist das andersrum?

01:08:58.000 --> 01:09:00.000
Das wäre dann Co-Variant oder Kontra-Variant?

01:09:01.000 --> 01:09:03.000
Genau, und das eine ist Co-Variant und das andere ist Contra-Variant,

01:09:03.000 --> 01:09:04.000
weil du eben sagst, okay, wenn du

01:09:04.000 --> 01:09:06.000
den als Generic verwendest,

01:09:07.000 --> 01:09:09.000
dann geht die Beziehung in die eine Richtung oder

01:09:09.000 --> 01:09:10.000
die Beziehung geht in die andere Richtung.

01:09:11.000 --> 01:09:13.000
Und das ist natürlich schön, dass man da

01:09:13.000 --> 01:09:15.000
zwei Worte genommen hat, die exakt gleich klingen.

01:09:15.000 --> 01:09:17.000
Also Co-Variant ist, wenn man quasi annotiert

01:09:17.000 --> 01:09:19.000
mit der Implementierung

01:09:19.000 --> 01:09:21.000
und Contra-Variant ist,

01:09:21.000 --> 01:09:22.000
wenn man mit der Basis

01:09:22.000 --> 01:09:24.000
annotiert, ja.

01:09:25.000 --> 01:09:26.000
Und In-Variant wäre dann, wenn man

01:09:26.000 --> 01:09:28.000
nicht beides verwenden darf, weil

01:09:28.000 --> 01:09:32.000
der sagt ja halt nö, das ist nicht genau das, was ich erwarte.

01:09:33.000 --> 01:09:34.000
Ja, irgendwie so.

01:09:34.000 --> 01:09:36.000
Für genauere Sachen muss man

01:09:36.000 --> 01:09:38.000
PEP484 lesen, das haben wir ja sicherlich

01:09:38.000 --> 01:09:38.000
alle schon gemacht.

01:09:42.000 --> 01:09:44.000
Muss man gar nicht genauer drauf eingehen.

01:09:45.000 --> 01:09:46.000
Ich packe die Grafik in die Schuhe

01:09:46.000 --> 01:09:47.000
und dann schauen wir mal.

01:09:48.000 --> 01:09:49.000
Schauen wir mal, ob das hilft.

01:09:51.000 --> 01:10:02.000
Ja aber genau Ich dachte auch so man kann das ja angeben und dann dachte ich so Ich hab das noch nie verwendet Ist das irgendwie hab ich was pass ich was oder Und was macht dann Bound

01:10:04.000 --> 01:10:05.000
Also weil das macht man ja irgendwie

01:10:05.000 --> 01:10:07.000
auch bei den Contra Variants oder

01:10:07.000 --> 01:10:08.000
ist das schon das?

01:10:09.000 --> 01:10:11.000
Steht zumindest in der Types,

01:10:11.000 --> 01:10:13.000
Pricing, Typing. Tatsächlich ist

01:10:13.000 --> 01:10:15.000
in dem PEP 484 eine sehr schöne Erklärung

01:10:15.000 --> 01:10:15.000
drin.

01:10:17.000 --> 01:10:19.000
Mit Employees und Managers.

01:10:21.000 --> 01:10:21.000
Wenn du

01:10:21.000 --> 01:10:24.000
eine Funktion hast, die eine Liste von Employee

01:10:24.000 --> 01:10:26.000
nimmst, kannst du

01:10:26.000 --> 01:10:27.000
da eine Liste von Managers reingeben?

01:10:28.000 --> 01:10:29.000
Und für manche

01:10:29.000 --> 01:10:32.000
Funktionen kann das Ja sein, wenn du

01:10:32.000 --> 01:10:33.000
halt sagst, okay, wir müssen Gehalt auszahlen, das

01:10:33.000 --> 01:10:36.000
müssen Angestellte kriegen und wenn die Angestellten

01:10:36.000 --> 01:10:38.000
Manager sind, dann ist es halt

01:10:38.000 --> 01:10:40.000
so. Kann aber

01:10:40.000 --> 01:10:41.000
auch Nein sein, dass du

01:10:41.000 --> 01:10:42.000
zum Beispiel

01:10:42.000 --> 01:10:45.000
keine Ahnung, alle

01:10:45.000 --> 01:10:48.000
Angestellten aufsetzt,

01:10:48.000 --> 01:10:48.000
die

01:10:48.000 --> 01:10:49.000
Manager-File.

01:10:50.000 --> 01:10:50.000
Genau.

01:10:52.000 --> 01:10:54.000
Nee, aber dass du zum Beispiel jemanden hinzufügst

01:10:54.000 --> 01:10:56.000
zu dieser Liste. Und wenn du sagst,

01:10:56.000 --> 01:10:58.000
okay, die Funktion nimmt eine Liste, die

01:10:58.000 --> 01:11:00.000
die Angestellte enthält, dann kannst du

01:11:00.000 --> 01:11:02.000
in diese Liste auch einen Angestellten reintun.

01:11:02.000 --> 01:11:04.000
Wenn du aber eine Liste von Managern

01:11:04.000 --> 01:11:05.000
reingegeben hast, dann geht das nicht.

01:11:07.000 --> 01:11:08.000
Und das

01:11:08.000 --> 01:11:10.000
ist jetzt eben genau so eine Frage, wo du

01:11:10.000 --> 01:11:11.000
beide Optionen haben kannst,

01:11:11.000 --> 01:11:14.000
also so eine Situation, wo du beide haben kannst

01:11:14.000 --> 01:11:16.000
und das

01:11:16.000 --> 01:11:18.000
tatsächlich auch eigentlich beantworten können

01:11:18.000 --> 01:11:19.000
musst, ob du da

01:11:19.000 --> 01:11:21.000
eine abgeleitete oder eine Basisklasse

01:11:21.000 --> 01:11:23.000
reingeben darfst. Eine Q-Variante

01:11:23.000 --> 01:11:25.000
oder eine Contra-Variante. Und der Bound ist dann

01:11:25.000 --> 01:11:26.000
quasi tatsächlich die,

01:11:27.000 --> 01:11:29.000
wenn dann erst die Manager-Revival, weil das die

01:11:29.000 --> 01:11:31.000
spezialisiertere Variante ist.

01:11:33.000 --> 01:11:35.000
Ja, wir haben noch mehr von dem

01:11:35.000 --> 01:11:37.000
Typing-Modul, damit wir uns noch mehr schöne Sachen

01:11:37.000 --> 01:11:39.000
dazu erzählen können und mehr ergänzen können mit

01:11:39.000 --> 01:11:41.000
präzisem Fachwissen. Und zwar den

01:11:41.000 --> 01:11:43.000
Type-Adias und die Type-Ware,

01:11:44.000 --> 01:11:45.000
die da noch irgendwie dazu können.

01:11:45.000 --> 01:11:47.000
Also was ist denn der Unterschied? Und man kann ja auch noch

01:11:47.000 --> 01:11:49.000
das schöne Keyword Type dazu schreiben

01:11:49.000 --> 01:11:50.000
und sowas.

01:11:51.000 --> 01:11:53.000
Ich meine, bei Type Alias, das kannst du auch

01:11:53.000 --> 01:11:55.000
einfach so hinschreiben, es ist nur eine explizitere

01:11:55.000 --> 01:11:57.000
Darstellung und manchmal ist es halt problematisch,

01:11:57.000 --> 01:11:59.000
wenn du zum Beispiel einfach einen String verwendest, den du ja auch

01:11:59.000 --> 01:12:01.000
quasi benutzen kannst, statt

01:12:01.000 --> 01:12:03.000
und manchmal muss man das ja auch

01:12:03.000 --> 01:12:04.000
um zyklische Imports zu vermeiden und so,

01:12:05.000 --> 01:12:07.000
dann ist halt unklar, was gemeint ist, wenn man

01:12:07.000 --> 01:12:08.000
nicht Type Alias davor schreibt.

01:12:08.000 --> 01:12:10.000
Also beispielsweise, wenn ich jetzt irgendwie eine Union habe,

01:12:10.000 --> 01:12:12.000
das kann jetzt mehrere Sachen sein, dann kann ich dann

01:12:12.000 --> 01:12:14.000
Type Alias für verwenden, dass das damit

01:12:14.000 --> 01:12:16.000
gemeint ist, in dem einen Namen geht. Ja, aber du könntest ja auch einfach

01:12:16.000 --> 01:12:18.000
hinschreiben, myUnion gleich

01:12:18.000 --> 01:12:20.000
und dann irgendwie

01:12:20.000 --> 01:12:22.000
der Typ, Pipe-Symbol,

01:12:22.000 --> 01:12:22.000
der andere.

01:12:24.000 --> 01:12:25.000
Das ist dann ein Type-Alias schon.

01:12:25.000 --> 01:12:28.000
Das selber kann ich annotieren mit, nein, ist es nicht?

01:12:28.000 --> 01:12:30.000
Ja, also du könntest damit dann wieder annotieren.

01:12:30.000 --> 01:12:32.000
Aber wenn du jetzt zum Beispiel

01:12:32.000 --> 01:12:34.000
da Strings verwenden wollen würdest

01:12:34.000 --> 01:12:35.000
für die Typen,

01:12:36.000 --> 01:12:38.000
dann geht es halt nicht mehr so richtig.

01:12:39.000 --> 01:12:40.000
Und dann macht,

01:12:40.000 --> 01:12:42.000
also Type-Alias macht das dann halt explizit,

01:12:42.000 --> 01:12:43.000
dass das halt sozusagen...

01:12:43.000 --> 01:12:46.000
Und die Type war,

01:12:46.000 --> 01:12:48.000
das hatten wir eben, TVK, TKV,

01:12:48.000 --> 01:12:49.000
warum TKV jetzt da

01:12:49.000 --> 01:12:51.000
im besonderen Sinne, weil ich diese kurzen Dinge,

01:12:51.000 --> 01:12:54.000
einer der Gründe, warum ich Go nicht leiten kann, sind diese

01:12:54.000 --> 01:12:56.000
einen Charakter

01:12:56.000 --> 01:12:58.000
Variablen haben, aber ja.

01:12:58.000 --> 01:13:00.000
Ja, das sind halt die Generics, oder, die wir vorhin hatten.

01:13:00.000 --> 01:13:01.000
Stefan, du hast angesetzt.

01:13:02.000 --> 01:13:02.000
Erklär uns, was Type war.

01:13:02.000 --> 01:13:04.000
Also ich habe jetzt ganz kurz diesen

01:13:04.000 --> 01:13:06.000
Pep4 aufgemacht und der ist

01:13:06.000 --> 01:13:07.000
wunderschön.

01:13:08.000 --> 01:13:09.000
Der ist super, oder?

01:13:09.000 --> 01:13:12.000
Also Type-Variable, also ich sage immer Type-Parameter

01:13:12.000 --> 01:13:14.000
dazu, aber das ist im Grunde genau das Gleiche.

01:13:14.000 --> 01:13:15.000
Das ist eben diese,

01:13:15.000 --> 01:13:17.000
ein Typ, der später durch einen

01:13:17.000 --> 01:13:19.000
konkreten Typ ersetzt wird. Das heißt, du kannst jetzt sagen,

01:13:19.000 --> 01:13:21.000
du hast diese Typvariable in diesem Beispiel

01:13:21.000 --> 01:13:23.000
von pep484 ist das st,

01:13:24.000 --> 01:13:25.000
seist type wird

01:13:25.000 --> 01:13:27.000
das heißen dort, weil da geht es um seist,

01:13:29.000 --> 01:13:29.000
wo du sagst,

01:13:30.000 --> 01:13:31.000
hey, du machst jetzt eine Funktion, die

01:13:31.000 --> 01:13:33.000
erlaubt

01:13:33.000 --> 01:13:35.000
x beliebige Typen,

01:13:36.000 --> 01:13:37.000
allerdings kannst du sie

01:13:37.000 --> 01:13:39.000
durch irgendeinen Bound,

01:13:39.000 --> 01:13:40.000
das ist das zweite dort,

01:13:41.000 --> 01:13:43.000
der zweite Parameter,

01:13:43.000 --> 01:13:46.000
einschränken. Also ein Bound sagt dir

01:13:46.000 --> 01:13:52.000
oder der generelle Typ-Rameter sagt dir, alle möglichen Werte, aber später

01:13:52.000 --> 01:13:55.000
nur ein konkreter. Und der Bound sagt dir,

01:13:56.000 --> 01:14:00.000
alle möglichen Werte, die auch diese Eigenschaften erfüllen, später ein

01:14:00.000 --> 01:14:04.000
konkreter. Und das ist dort in diesem Beispiel recht gut, weil du jetzt seist als Bound

01:14:04.000 --> 01:14:06.000
definiert, was bedeutet, dass du

01:14:06.000 --> 01:14:10.000
eine Länge definieren

01:14:10.000 --> 01:14:12.000
können musst oder Länge lesen

01:14:12.000 --> 01:14:14.000
können musst.

01:14:15.000 --> 01:14:16.000
In Python hast du nur

01:14:16.000 --> 01:14:18.000
diese Hilfsfunktion, du hast ja selten

01:14:18.000 --> 01:14:20.000
Methoden auf Klassen, soweit ich das

01:14:20.000 --> 01:14:21.000
weiß.

01:14:22.000 --> 01:14:23.000
Deswegen brauchst du halt

01:14:23.000 --> 01:14:26.000
überall diese Bounds. Andererseits

01:14:26.000 --> 01:14:28.000
könntest du ja sagen, du hast irgendeine

01:14:28.000 --> 01:14:29.000
Subklasse oder so.

01:14:30.000 --> 01:14:32.000
Aber Bound ist auch etwas,

01:14:32.000 --> 01:14:34.000
das kennen wir in anderen Programmiersprachen auch,

01:14:34.000 --> 01:14:36.000
in TypeScript wird das als

01:14:36.000 --> 01:14:38.000
Konstrant bezeichnet. Aber im Grund geht es darum, dass du

01:14:38.000 --> 01:14:41.000
einfach vordefinierst, du hast ein paar Eigenschaften,

01:14:41.000 --> 01:14:42.000
die du sicherstellen willst.

01:14:42.000 --> 01:14:44.000
In dem Fall, was dort beim PEP484 ist,

01:14:44.000 --> 01:14:46.000
mit diesem Upper Bound, sagst du einfach,

01:14:46.000 --> 01:14:48.000
du willst die Möglichkeit haben, eine Länge zu berechnen.

01:14:49.000 --> 01:14:50.000
Du willst einfach wissen, da gibt es eine Size,

01:14:51.000 --> 01:15:03.000
das hat eine gewisse L was auch immer Spannend w es ob ich dort einen String reingeben kann weil man kann ja die L von einem String definieren Ja kannst du Alles was Lend von irgendwas hat

01:15:03.000 --> 01:15:05.000
ist size. Also ich kenne kein

01:15:05.000 --> 01:15:06.000
Python, aber ich habe diesen Code jetzt gelesen und weiß

01:15:06.000 --> 01:15:08.000
sofort, was ich da zu erwarten habe,

01:15:09.000 --> 01:15:10.000
weil ein String muss auch

01:15:10.000 --> 01:15:12.000
eine Länge rauskriegen.

01:15:13.000 --> 01:15:14.000
Schon cool.

01:15:15.000 --> 01:15:16.000
Und das ist

01:15:16.000 --> 01:15:18.000
auch sehr interessant hier, weil also diese

01:15:18.000 --> 01:15:20.000
Type Variable, die gerade in diesem Beispiel,

01:15:20.000 --> 01:15:22.000
ich habe es zufällig auch gerade offen,

01:15:22.000 --> 01:15:23.000
benutzt wird.

01:15:24.000 --> 01:15:26.000
Die wird in dieser Funktion, da wird eine Funktion definiert,

01:15:26.000 --> 01:15:28.000
die heißt longer und die nimmt zwei Variablen

01:15:28.000 --> 01:15:30.000
x und y und die sind beide vom Typ st

01:15:30.000 --> 01:15:32.000
und der Rückgabewert ist

01:15:32.000 --> 01:15:33.000
ebenfalls st.

01:15:34.000 --> 01:15:36.000
Und das ist eine sehr interessante Sache, weil das eben

01:15:36.000 --> 01:15:38.000
bedeutet, du kannst hier

01:15:38.000 --> 01:15:39.000
zwei Sachen reingeben, die von

01:15:39.000 --> 01:15:42.000
der gleichen Sorte sind und kriegst wieder eins raus,

01:15:42.000 --> 01:15:43.000
was wieder von der gleichen Sorte ist.

01:15:44.000 --> 01:15:46.000
Aber wir sagen gar nicht genau, was das für

01:15:46.000 --> 01:15:47.000
eine Sorte ist, sondern wir sagen nur, das muss

01:15:47.000 --> 01:15:49.000
als Anforderung haben,

01:15:50.000 --> 01:15:51.000
das Minimum, was es erfüllen muss,

01:15:51.000 --> 01:15:53.000
das ist der Bound, ich muss davon die Länge

01:15:53.000 --> 01:15:54.000
abrufen können.

01:15:55.000 --> 01:15:57.000
Und das hat diese Funktion

01:15:57.000 --> 01:15:59.000
schon sehr genau spezifiziert.

01:15:59.000 --> 01:16:01.000
Die Spezifikation dieser Funktion,

01:16:01.000 --> 01:16:03.000
also longer x, y, ist ja

01:16:03.000 --> 01:16:04.000
erst mal sehr lose.

01:16:05.000 --> 01:16:07.000
Und jetzt durch diese Typvariablen und durch den

01:16:07.000 --> 01:16:09.000
Bound ist es doch relativ genau spezifiziert

01:16:09.000 --> 01:16:11.000
und auch sehr exakt,

01:16:11.000 --> 01:16:12.000
würde ich sagen.

01:16:12.000 --> 01:16:15.000
Was ich sehr spannend finde an dem Beispiel, und das ist

01:16:15.000 --> 01:16:16.000
wahrscheinlich jetzt so ein Python-Eigenwort,

01:16:16.000 --> 01:16:25.000
aber im ersten Aufruf wird dort dieser generische Typ-Parameter oder diese Type-Ware ersetzt durch eine List.

01:16:25.000 --> 01:16:27.000
Das ist, glaube ich, die eckigen Klammern.

01:16:27.000 --> 01:16:31.000
Im zweiten Aufruf, da hast du geschwungene Klammern, wird es durch ein Set ersetzt.

01:16:32.000 --> 01:16:33.000
Also der Typ wird durch ein Set ersetzt.

01:16:33.000 --> 01:16:38.000
Aber im dritten, da ist im ersten Aufruf eckige Klammern, im zweiten Parameter sind geschwungene Klammern.

01:16:39.000 --> 01:16:43.000
Da wird der Parent-Type davon eine Collection verwendet, wo du sagst,

01:16:43.000 --> 01:16:45.000
hey, okay, ist eine List, ist eine Set, also es könnte beides sein.

01:16:45.000 --> 01:16:47.000
du nimmst einfach was, was

01:16:47.000 --> 01:16:49.000
beide beschreibt. Finde ich cool,

01:16:49.000 --> 01:16:51.000
dass das das Typsystem so macht. Normalerweise würde

01:16:51.000 --> 01:16:53.000
TypeScript dir da vielleicht einen Fehler

01:16:53.000 --> 01:16:55.000
werfen. TypeScript würde da sagen, hey,

01:16:56.000 --> 01:16:57.000
wenn du das einmal

01:16:57.000 --> 01:16:59.000
durch einen Typ ersetzt, dann musst du auch im zweiten

01:16:59.000 --> 01:17:01.000
Parameter den gleichen Typ verwenden und so

01:17:01.000 --> 01:17:03.000
findest du aber in der Hierarchie tatsächlich

01:17:03.000 --> 01:17:05.000
einen Parent-Type, den du

01:17:05.000 --> 01:17:06.000
nutzen kannst. Das ist ziemlich geil.

01:17:07.000 --> 01:17:09.000
Also, richtig

01:17:09.000 --> 01:17:11.000
cool. Ja, das ist ziemlich schön.

01:17:14.000 --> 01:17:14.000
Also,

01:17:14.000 --> 01:17:16.000
nämlich auch so, dass ich das jetzt verwenden möchte.

01:17:16.000 --> 01:17:17.000
Muss ich ganz ehrlich sagen.

01:17:17.000 --> 01:17:18.000
Ich glaube, ihr habt es so weit.

01:17:20.000 --> 01:17:21.000
Sehr gut.

01:17:21.000 --> 01:17:23.000
Viele Programmiersprachen-Features

01:17:23.000 --> 01:17:25.000
werden ja durch Knight umgesetzt.

01:17:26.000 --> 01:17:27.000
Das ist bei Python

01:17:27.000 --> 01:17:30.000
auch nicht anders. Viele Sachen sind einfach

01:17:30.000 --> 01:17:32.000
aus Knight durch andere Sprachen entstanden.

01:17:34.000 --> 01:17:35.000
Den größten Knight habe ich ja durch

01:17:35.000 --> 01:17:38.000
die Import-Signatur. Das macht einfach

01:17:38.000 --> 01:17:39.000
so viel einfacher.

01:17:40.000 --> 01:17:42.000
In JavaScript ist es umgekehrt. Du importierst

01:17:42.000 --> 01:17:43.000
zuerst die Einzelelemente

01:17:43.000 --> 01:17:44.000
aus dem Paket.

01:17:45.000 --> 01:17:47.000
Und das ist reine Ästhetik. So ist viel

01:17:47.000 --> 01:17:49.000
klarer. Du spezifisierst zuerst

01:17:49.000 --> 01:17:51.000
das Paket und dann importierst du die Sachen draus.

01:17:51.000 --> 01:17:54.000
Jeder Editor freut sich, wenn er das so kriegen kann.

01:17:55.000 --> 01:17:56.000
Ja.

01:17:57.000 --> 01:17:57.000
Was mich noch

01:17:57.000 --> 01:17:59.000
interessieren würde hier an der Stelle ist

01:17:59.000 --> 01:18:01.000
diese Overloads, die da mit drinstehen.

01:18:01.000 --> 01:18:03.000
Das ist ja auch so eine Sache, die man nur

01:18:03.000 --> 01:18:05.000
bei den Type Annotations findet oder

01:18:05.000 --> 01:18:08.000
auch woanders, wo halt derselbe Methodenname

01:18:08.000 --> 01:18:09.000
mehrfach hintereinander definiert wird.

01:18:10.000 --> 01:18:11.000
Was macht denn das genau?

01:18:13.000 --> 01:18:13.000
Schreibst du in

01:18:13.000 --> 01:18:16.000
Python dort dann beide Methoden

01:18:16.000 --> 01:18:18.000
aus? Also implementierst du da beide Methoden?

01:18:18.000 --> 01:18:20.000
Ah, in Python musst du dich da anstrengen dafür.

01:18:20.000 --> 01:18:21.000
Oder sind das nur die Signaturen?

01:18:22.000 --> 01:18:24.000
In Python musst du dich da anstrengen

01:18:24.000 --> 01:18:25.000
dafür. Das hat ja nicht mal viel mit

01:18:25.000 --> 01:18:27.000
ja, es hat vielleicht schon was mit Hypes

01:18:27.000 --> 01:18:29.000
zu tun, aber

01:18:29.000 --> 01:18:31.000
also so richtiges Overloading

01:18:31.000 --> 01:18:32.000
gibt es ja gar nicht in Python.

01:18:33.000 --> 01:18:35.000
Du fügst eine weitere Signatur hinzu

01:18:35.000 --> 01:18:37.000
zur Methode. Ja genau, was macht denn das?

01:18:37.000 --> 01:18:39.000
Warum macht man denn das? Du hast noch nicht zwei Funktionen,

01:18:39.000 --> 01:18:40.000
du hast zwei Signaturen.

01:18:41.000 --> 01:18:43.000
Du hast eine Funktion, die

01:18:43.000 --> 01:19:01.000
Also es ist so, der ganz grundlegende Prozess ist, dass eine Funktion in Python eine Variable ist, die halt ein Funktionssubjekt enthält. Und diese Variable hat einen Namen und diesen Namen, der ist eindeutig, den kannst du nur einmal geben. Und zu diesem Namen kannst du auch nur diese eine Funktion geben.

01:19:01.000 --> 01:19:21.000
Was du jetzt aber machst, um Überladung zu machen und das, ich erkläre es gleich noch für die Zuhörer, ist, dass du sagst, du definierst eine Basismethode und der fügst du dann eine weitere Signatur hinzu. Und wenn diese, da ist dann eben so ein, durch Dekoratoren hast du so einen Mechanismus, der diese Signaturen entsprechend überprüft.

01:19:22.000 --> 01:19:24.000
So, was ist Überladung überhaupt und was erreicht man damit?

01:19:25.000 --> 01:19:30.000
Überladung ist, wenn du eine Funktion, also ganz klassisch aus dem Java-Umfeld,

01:19:30.000 --> 01:19:34.000
wenn du eine Funktion hast, die heißt add und die definierst du für float und float

01:19:34.000 --> 01:19:37.000
und dann kommt hinterher wieder ein float raus.

01:19:37.000 --> 01:19:41.000
Dann funktioniert die ganz einwandfrei für floats, aber du kannst damit nicht int adden.

01:19:41.000 --> 01:19:44.000
Du kannst keine Integer addieren, weil der Compiler dir sagt,

01:19:44.000 --> 01:19:47.000
ich habe die Funktion gefunden, aber die geht nur für floats.

01:19:48.000 --> 01:19:51.000
Was du jetzt in Java machst, ist, du schreibst eine zweite Funktion,

01:19:51.000 --> 01:19:55.000
die auch Add heißt, aber die eine andere Signatur hat.

01:19:55.000 --> 01:19:57.000
Und die wird durch das Kompilat

01:19:57.001 --> 01:19:58.000
zu einer anderen Funktion.

01:19:58.000 --> 01:20:00.000
Das heißt, zum Zeitpunkt des Kompilierens

01:20:00.000 --> 01:20:02.000
kann der Compiler sagen, ah, du meintest

01:20:02.000 --> 01:20:04.000
diese Funktion mit der Signatur oder

01:20:04.000 --> 01:20:06.000
du meintest diese Funktion mit der Signatur.

01:20:07.000 --> 01:20:08.000
Und das geht auch in

01:20:08.000 --> 01:20:10.000
TypeScript, wenn ich mich recht erinnere,

01:20:11.000 --> 01:20:12.000
dass du überladene

01:20:12.000 --> 01:20:14.000
Methoden hast, die dann eben durch den

01:20:14.000 --> 01:20:17.000
Compiler zum Zeitpunkt des Compilerns

01:20:17.000 --> 01:20:18.000
die richtige

01:20:18.000 --> 01:20:21.000
Zuweisung bekommen. Die sind dann im JavaScript-Kompilat

01:20:21.000 --> 01:20:22.000
heißen die dann unterschiedlich, weil

01:20:22.000 --> 01:20:23.000
die eben da unterschiedlich sind.

01:20:23.000 --> 01:20:25.000
Das ist genau der Unterschied.

01:20:25.000 --> 01:20:37.000
Ein Overload in TypeScript ist im Grund nur eine andere Funktionssignatur über der tatsächlichen.

01:20:37.000 --> 01:20:39.000
Du musst mindestens zwei angeben.

01:20:39.000 --> 01:20:44.000
Eine, die dem Typsystem mitgeteilt wird als Nutzungssignatur

01:20:44.000 --> 01:20:48.000
und eine, die du verwenden kannst, um tatsächlich die Funktion zu implementieren.

01:20:48.000 --> 01:20:50.000
Und dann kannst du so viele Overload schreiben, wie du willst.

01:20:50.000 --> 01:20:51.000
und du hast dort einfach unterschiedliche

01:20:51.000 --> 01:20:54.000
Aufrufe, durch die du

01:20:54.000 --> 01:20:56.000
durchgehen kannst, aber im Endeffekt wird

01:20:56.000 --> 01:20:58.000
nur eine Methode aufgerufen

01:20:58.000 --> 01:20:59.000
oder eine Funktion aufgerufen.

01:21:00.000 --> 01:21:02.000
Deswegen habe ich genauso nachgefragt,

01:21:02.000 --> 01:21:04.000
weil ich bin mir nicht sicher, wie das jetzt in Python funktioniert,

01:21:04.000 --> 01:21:06.000
weil es ist spannend.

01:21:07.000 --> 01:21:07.000
Es ist

01:21:07.000 --> 01:21:09.000
so Führungslieder.

01:21:10.000 --> 01:21:12.000
In Python ist es ein bisschen anders.

01:21:12.000 --> 01:21:14.000
In Python musst du das eben über Dekoratoren

01:21:14.000 --> 01:21:16.000
machen, weil du diesen Namen nicht mehrfach

01:21:16.000 --> 01:21:18.000
haben darfst und was

01:21:18.000 --> 01:21:19.000
da im Wesentlichen passiert ist, du sagst,

01:21:20.000 --> 01:21:24.000
wenn die Methode aufgerufen wird mit zwei Variablen

01:21:24.000 --> 01:21:28.000
oder mit Argumenten, die diese Signatur entsprechen,

01:21:28.000 --> 01:21:31.000
dann rufe bitte diese Subsignatur auf.

01:21:32.000 --> 01:21:34.000
Also du fügst da quasi eine weitere Funktion hinzu,

01:21:34.000 --> 01:21:36.000
die nur in bestimmten Fällen aufgerufen wird.

01:21:36.000 --> 01:21:38.000
Aber das ist was, was zur Laufzeit passiert.

01:21:38.000 --> 01:21:42.000
Also zur Laufzeit wird dann entschieden,

01:21:42.000 --> 01:21:46.000
welche Submethode aufgerufen wird.

01:21:46.000 --> 01:21:49.000
Das ist im Wesentlichen ein Match Case,

01:21:49.000 --> 01:21:51.000
der da vorsteht.

01:21:51.000 --> 01:21:54.000
Ich weiß nicht, ob das im Typing-Zusammenhang nicht was anderes ist.

01:21:54.000 --> 01:21:56.000
Also ich meine, es gibt diese Overload-

01:21:56.000 --> 01:21:58.000
Geschichten vielleicht in Klassen,

01:21:58.000 --> 01:21:59.000
aber ich meine hier auch bei den

01:21:59.000 --> 01:22:01.000
bei Funktionen, wenn ich jetzt

01:22:01.000 --> 01:22:04.000
einfach das sozusagen für diese Typ-Annotation

01:22:04.000 --> 01:22:06.000
verwenden will, dann ist es, soweit ich sehen kann,

01:22:06.000 --> 01:22:07.000
auch so. Es gibt die Funktion einmal,

01:22:08.000 --> 01:22:10.000
aber ich kann halt viele

01:22:10.000 --> 01:22:12.000
sozusagen mit Overload

01:22:12.000 --> 01:22:14.000
dekorierten Funktionen

01:22:14.000 --> 01:22:15.000
haben, die keine Implementation haben,

01:22:15.000 --> 01:22:17.000
aber wo ich sozusagen nur

01:22:17.000 --> 01:22:19.000
quasi die unterschiedlichen

01:22:19.000 --> 01:22:21.000
möglichen Arten, wie ich das

01:22:21.000 --> 01:22:23.000
wie das aufrufen werden kann, halt

01:22:23.000 --> 01:22:26.000
annotiere, weil ich das nicht in eine Annotation schreiben kann,

01:22:26.000 --> 01:22:27.000
weil geht halt nicht.

01:22:28.000 --> 01:22:29.000
Und ja.

01:22:30.000 --> 01:22:31.000
Achso, okay. Da gibt's

01:22:31.000 --> 01:22:33.000
zwei, also es gibt da, dann hab ich, also es gibt

01:22:33.000 --> 01:22:36.000
mehrere Overload-Dinge,

01:22:36.000 --> 01:22:38.000
denke ich. Genau, also das

01:22:38.000 --> 01:22:40.000
das ist blöd, ja.

01:22:40.000 --> 01:22:42.000
Es ist blöd, dass diese Sachen in

01:22:42.000 --> 01:22:43.000
unterschiedlichen Sprachen unterschiedliche Dinge bedeuten.

01:22:46.000 --> 01:22:47.000
Es ist, also

01:22:47.000 --> 01:22:49.000
wenn ich der Kaiser wäre, dann wäre das anders.

01:22:52.000 --> 01:22:56.000
Also das ist tatsächlich was, was ich vermisst habe

01:22:56.000 --> 01:22:57.000
an Python. Als ich zu Python gekommen bin,

01:22:57.000 --> 01:22:59.000
aus Java. In Java kannst du sagen, ich habe hier

01:22:59.000 --> 01:23:01.000
eine Funktion, die heißt add und die nimmt Integer

01:23:01.000 --> 01:23:03.000
und ich habe eine Funktion add, die nimmt Strings

01:23:03.000 --> 01:23:06.000
und ich habe eine Funktion add, die nimmt, was weiß ich,

01:23:06.000 --> 01:23:07.000
Listen. Und die machen

01:23:07.000 --> 01:23:09.000
sehr unterschiedliche Dinge, aber im Endeffekt

01:23:09.000 --> 01:23:11.000
das gleiche Semantische. Die fügen die aneinander.

01:23:12.000 --> 01:23:13.000
Und die heißen gleich,

01:23:14.000 --> 01:23:15.000
weil die das gleiche machen. Und sowas

01:23:15.000 --> 01:23:17.000
gibt es in Python nicht, weil in Python musst du

01:23:17.000 --> 01:23:20.000
jedes Mal einen neuen

01:23:20.000 --> 01:23:21.000
Namen haben dafür oder einen neuen Scope

01:23:21.000 --> 01:23:24.000
oder so. Dafür gibt es

01:23:24.000 --> 01:23:24.000
Single Dispatch.

01:23:26.000 --> 01:23:27.000
Ja, das hat

01:23:27.000 --> 01:23:30.000
damit zu tun, dass

01:23:30.000 --> 01:23:31.000
in Java überhaupt möglich ist, dass du

01:23:31.000 --> 01:23:33.000
den gleichen Namen mehrmals vergeben kannst.

01:23:35.000 --> 01:23:35.000
Ja, weil die beim

01:23:35.000 --> 01:23:37.000
Kompilieren die Namen, weil die Namen weg sind

01:23:37.000 --> 01:23:38.000
beim Kompilieren.

01:23:38.000 --> 01:23:39.000
Nein, weil die

01:23:39.000 --> 01:23:42.000
Funktionssignaltypen haben.

01:23:42.000 --> 01:23:44.000
Nein, weil die Funktionssignaltypen haben.

01:23:44.000 --> 01:23:46.000
weil Java die Typen

01:23:46.000 --> 01:23:48.000
erfordert

01:23:48.000 --> 01:23:49.000
und dadurch

01:23:49.000 --> 01:23:52.000
ist einfach genug Unterschied da, um das

01:23:52.000 --> 01:23:53.000
zu identifizieren können.

01:23:54.000 --> 01:23:56.000
Genau, es sind unterschiedliche Funktionen. Also die Funktion

01:23:56.000 --> 01:23:58.000
addIntInt ist eine andere Funktion

01:23:58.000 --> 01:24:00.000
als die Funktion addFloatFloat.

01:24:01.000 --> 01:24:02.000
Und darum ist natürlich ein JavaScript

01:24:02.000 --> 01:24:04.000
und Python

01:24:06.000 --> 01:24:06.000
halt

01:24:06.000 --> 01:24:08.000
komplett anders, weil im Endeffekt

01:24:08.000 --> 01:24:10.000
hast du halt nur eine Funktion mit ein paar Parametern

01:24:10.000 --> 01:24:12.000
und die Typen sind ja, wie wir mitbekommen

01:24:12.000 --> 01:24:14.000
haben, eigentlich wurscht.

01:24:14.000 --> 01:24:14.000
Die sind dann weg.

01:24:15.000 --> 01:24:17.000
Ja, zur Laufzeit auf jeden Fall.

01:24:17.000 --> 01:24:20.000
Aber diesen Mechanismus, den kriegst du hin,

01:24:20.000 --> 01:24:21.000
der heißt Single Dispatch.

01:24:22.000 --> 01:24:24.000
From Functools import Single Dispatch.

01:24:24.000 --> 01:24:24.000
PEP 443.

01:24:26.000 --> 01:24:27.000
Das, was ihr beschrieben habt,

01:24:28.000 --> 01:24:29.000
das heißt Overload,

01:24:29.000 --> 01:24:32.000
das ist ja was ganz anderes. Python Lang Util.

01:24:32.000 --> 01:24:33.000
Äh.

01:24:34.000 --> 01:24:34.000
Okay.

01:24:35.000 --> 01:24:37.000
Ich hab's jetzt hier aus From Typing.

01:24:38.000 --> 01:24:40.000
Also, so wie ich das

01:24:40.000 --> 01:24:41.000
gesehen hab, es gibt auch ein sehr schönes Beispiel

01:24:41.000 --> 01:24:43.000
dafür, das ist auch aus dem Fluent Python

01:24:43.000 --> 01:24:45.000
Buch, habe ich das da,

01:24:47.000 --> 01:24:48.000
also das ist halt so ein Beispiel

01:24:48.000 --> 01:24:50.000
für Methoden, die halt eigentlich

01:24:50.000 --> 01:24:51.000
in, also die hat auch so ein Problem,

01:24:52.000 --> 01:25:02.000
dass man mit Type halt so hat beschreiben n dass man dass halt die Typ nicht so also die ist ja auch eine Sprache ist halt eine andere Art das hinzuschreiben

01:25:02.000 --> 01:25:04.000
Und die ist halt nicht so expressiv wie Python selber.

01:25:05.000 --> 01:25:06.000
Das heißt, wenn ich jetzt Funktionen habe,

01:25:06.000 --> 01:25:08.000
wie zum Beispiel min und max,

01:25:08.000 --> 01:25:08.000
jetzt weiß ich gar nicht,

01:25:08.000 --> 01:25:11.000
ob es das in der JavaScript-Welt auch so gibt,

01:25:12.000 --> 01:25:15.000
aber die kann ich halt sehr schön in Python hinschreiben,

01:25:15.000 --> 01:25:18.000
so in irgendwie so 20 Zeilen oder sowas.

01:25:19.000 --> 01:25:21.000
Und ist sehr schön zu lesen,

01:25:21.000 --> 01:25:22.000
ist nicht kompliziert

01:25:22.000 --> 01:25:25.000
und die Typ-Annotation dafür

01:25:25.000 --> 01:25:27.000
ist aber sehr, sehr schwer, weil das

01:25:27.000 --> 01:25:29.000
halt so super generisch ist und dann kann man noch ein

01:25:29.000 --> 01:25:31.000
Callback übergeben, das halt

01:25:31.000 --> 01:25:33.000
irgendwie zum Sortieren verwendet wird

01:25:33.000 --> 01:25:34.000
und sowas und

01:25:34.000 --> 01:25:37.000
ja, die korrekten

01:25:37.000 --> 01:25:39.000
Type-Annotationen für Min und Max sind

01:25:39.000 --> 01:25:41.000
halt sehr viel länger als die Implementation

01:25:41.000 --> 01:25:42.000
und das ist halt,

01:25:42.000 --> 01:25:44.000
liegt halt daran, dass man das

01:25:44.000 --> 01:25:47.000
in dieser neuen Annotationssprache

01:25:47.000 --> 01:25:48.000
halt nicht so gut hinschreiben kann

01:25:48.000 --> 01:25:51.000
und dafür, also da hast du dann halt so irgendwie

01:25:51.000 --> 01:25:52.000
ich weiß nicht, zig Overloads, weil

01:25:52.000 --> 01:25:55.000
du kannst das sowieso immer nur

01:25:55.000 --> 01:25:57.000
quasi für einen Teil

01:25:57.000 --> 01:25:59.000
der, wie man das aufrufen kann, halt

01:25:59.000 --> 01:26:00.000
annotieren und dann musst du das halt

01:26:00.000 --> 01:26:03.000
zehn Dinger übereinander häufen,

01:26:03.000 --> 01:26:04.000
um das halt irgendwie

01:26:04.000 --> 01:26:06.000
abgebildet zu kriegen und

01:26:06.000 --> 01:26:08.000
ja, und auch in diesen Dingern sind dann halt,

01:26:09.000 --> 01:26:11.000
waren halt lange Fehler

01:26:11.000 --> 01:26:13.000
drin und die sind halt auch echt

01:26:13.000 --> 01:26:14.000
schwer zu finden, also ja.

01:26:16.000 --> 01:26:17.000
Und die machen ja auch überhaupt

01:26:17.000 --> 01:26:18.000
gar nichts, diese Fehler, jetzt mal ganz ehrlich.

01:26:19.000 --> 01:26:21.000
Ja gut, na gut, also

01:26:21.000 --> 01:26:23.000
Also irgendjemand hat dann halt...

01:26:23.000 --> 01:26:24.000
Sie haben ja oft mal lange genug was gemacht,

01:26:24.000 --> 01:26:25.000
was sie keinen gefunden hat.

01:26:25.000 --> 01:26:27.000
Es kann ja sein, du rufst das halt auf,

01:26:27.000 --> 01:26:28.000
lässt es auf eine bestimmte Art

01:26:28.000 --> 01:26:30.000
und dann läuft dein Type-Checker drüber

01:26:30.000 --> 01:26:32.000
und der sagt, der spuckt dir dann halt

01:26:32.000 --> 01:26:33.000
irgendeine Fehlermeldung aus,

01:26:33.000 --> 01:26:34.000
die vollkommen unverständlich ist

01:26:34.000 --> 01:26:36.000
und das verdirbt dir halt den Vormittag oder so,

01:26:36.000 --> 01:26:38.000
weil du verstehst gar nicht, wo das Problem ist.

01:26:38.000 --> 01:26:39.000
Und dann war es halt nicht mal wirklich ein Problem,

01:26:40.000 --> 01:26:41.000
sondern es ist einfach nur etwas,

01:26:41.000 --> 01:26:43.000
was halt in den Annotationen kaputt war

01:26:43.000 --> 01:26:45.000
und du hast es korrekt aufgerufen.

01:26:45.000 --> 01:26:46.000
Das ist ja schon ärgerlich.

01:26:47.000 --> 01:26:49.000
Also ich meine, ja, also...

01:26:49.000 --> 01:26:51.000
Ja, gut.

01:26:51.000 --> 01:26:53.000
Zugegeben, ja.

01:26:53.000 --> 01:26:57.000
Aber was war jetzt die Lösung, Jochen?

01:26:57.000 --> 01:27:00.000
Ich habe dich jetzt unterbrochen, aber gibt es da jetzt eine Lösung dafür?

01:27:00.000 --> 01:27:01.000
Kann ich jetzt da Overload sagen?

01:27:02.000 --> 01:27:06.000
Genau, und du kannst jetzt sozusagen, wenn du eine Funktion annotieren möchtest,

01:27:06.000 --> 01:27:08.000
aber die Annotation nicht einfach so hinschreiben kannst,

01:27:08.000 --> 01:27:11.000
dann kannst du die möglichen Arten, wie das halt,

01:27:12.000 --> 01:27:18.000
also wenn du mehrere Annotationen hinschreiben musst für die Funktion,

01:27:18.000 --> 01:27:19.000
kannst du das per Overload hinschreiben.

01:27:19.000 --> 01:27:21.000
hast dann halt der Methoden-Body

01:27:21.000 --> 01:27:23.000
oder Funktions-Body ist

01:27:23.000 --> 01:27:25.000
einfach Ellipsis, also Punkt, Punkt, Punkt.

01:27:26.000 --> 01:27:27.000
Und

01:27:27.000 --> 01:27:29.000
genau, dann kannst du halt alle Arten, wie man

01:27:29.000 --> 01:27:31.000
das Ding halt getypt aufrufen kann,

01:27:31.000 --> 01:27:32.000
halt hinschreiben.

01:27:33.000 --> 01:27:35.000
So richtig schön sieht das aber auch nicht aus.

01:27:35.000 --> 01:27:36.000
Nee, das sieht nicht schön aus.

01:27:40.000 --> 01:27:41.000
Ausgedehnt.

01:27:42.000 --> 01:27:43.000
Ich würde es zum Beispiel in TypeScript

01:27:43.000 --> 01:27:45.000
auch nicht immer verwenden.

01:27:45.000 --> 01:27:47.000
Meistens ist es ein Codespell, wenn du

01:27:47.000 --> 01:27:49.000
Methoden oder Funktionen hast,

01:27:50.000 --> 01:27:51.000
die mehr können soll,

01:27:52.000 --> 01:27:53.000
als für das, was sie

01:27:53.000 --> 01:27:55.000
beschreibt. Ja, so ein bisschen so eine Krücke,

01:27:55.000 --> 01:27:56.000
warum machen wir das denn nicht?

01:27:57.000 --> 01:27:59.000
Vielleicht, wenn man so ein Public-API-Interface hat,

01:27:59.000 --> 01:28:02.000
was unbedingt benutzt bleiben muss, aus irgendwelchen Gründen.

01:28:03.000 --> 01:28:03.000
Vielleicht für Legacy

01:28:03.000 --> 01:28:05.000
oder sowas. Ja, also in JavaScript gibt es es, weil

01:28:05.000 --> 01:28:07.000
also in TypeScript gibt es es,

01:28:07.000 --> 01:28:08.000
weil du halt in JavaScript

01:28:08.000 --> 01:28:11.000
Parameter weglassen kannst

01:28:11.000 --> 01:28:13.000
oder

01:28:13.000 --> 01:28:13.000
oder

01:28:13.000 --> 01:28:17.000
Parameter an unterschiedlichen Positionen

01:28:17.000 --> 01:28:18.000
auch was anderes heißen.

01:28:19.000 --> 01:28:21.000
Und da der TypeScript irgendeine Methode

01:28:21.000 --> 01:28:22.000
braucht, um das darzustellen.

01:28:24.000 --> 01:28:24.000
Und deswegen haben wir es.

01:28:25.000 --> 01:28:27.000
Ja, gut, wenn man Sternchen, Komma, Quark

01:28:27.000 --> 01:28:29.000
schreibt oder sowas. Also gerade dieses

01:28:29.000 --> 01:28:31.000
Ad-Beispiel von Johannes, das würde ich

01:28:31.000 --> 01:28:33.000
eigentlich jetzt den TypeScript mit

01:28:33.000 --> 01:28:35.000
Generics umsetzen.

01:28:36.000 --> 01:28:37.000
Ja, gut.

01:28:38.000 --> 01:28:39.000
Wenn du jetzt

01:28:39.000 --> 01:28:41.000
die Methode Add

01:28:41.000 --> 01:28:43.000
für Integer und die Methode Add für String hast,

01:28:43.000 --> 01:28:45.000
musst du ja schon zwei unterschiedliche

01:28:45.000 --> 01:28:46.000
Implementierungen haben auch.

01:28:46.000 --> 01:28:49.000
Also an irgendeiner Stelle musst du ja deine Implementierung

01:28:49.000 --> 01:28:50.000
verzweigen.

01:28:51.000 --> 01:28:53.000
Nicht in JavaScript.

01:28:54.000 --> 01:28:55.000
Ja, wenn du Plus verwendest,

01:28:55.000 --> 01:28:57.000
okay, aber dann musst du das Plus irgendwo hin verzweigen,

01:28:57.000 --> 01:28:59.000
weil das macht ja sehr unterschiedliche Dinge.

01:29:00.000 --> 01:29:00.000
Ja.

01:29:01.000 --> 01:29:03.000
Dann kann ich das dann netto überschreiben.

01:29:04.000 --> 01:29:05.000
Ja, ja.

01:29:06.000 --> 01:29:07.000
Ja.

01:29:07.000 --> 01:29:09.000
Was mir noch

01:29:09.000 --> 01:29:11.000
fehlt, wir haben schon relativ viel gesagt,

01:29:11.000 --> 01:29:13.000
aber es ist sowas wie, ich glaube es ist eben schon

01:29:13.000 --> 01:29:15.000
einmal gefallen, sowas wie rekursive Types oder sowas,

01:29:15.000 --> 01:29:17.000
Wenn ich zum Beispiel einen JSON-Type definiere.

01:29:17.000 --> 01:29:19.000
Oh, sag doch nicht sowas.

01:29:21.000 --> 01:29:22.000
Kapitel 7.

01:29:24.000 --> 01:29:27.000
Du bist ja noch weit entfernt von Kapitel 7.

01:29:30.000 --> 01:29:35.000
Ja, also rekursive Types ist schon nötig.

01:29:35.000 --> 01:29:37.000
Wenn du jetzt zum Beispiel irgendwie eine Liste definieren willst,

01:29:37.000 --> 01:29:38.000
eine einfach verkettete Liste,

01:29:39.000 --> 01:29:40.000
dann hast du dort nur einen Knoten

01:29:40.000 --> 01:29:42.000
und du verweist auf den nächsten Knoten.

01:29:45.000 --> 01:29:46.000
Aber das ist eigentlich nur ein Typsystem

01:29:46.000 --> 01:29:48.000
für 100. Also du musst halt irgendwie

01:29:48.000 --> 01:29:51.000
die Möglichkeit haben, dass du Typen

01:29:51.000 --> 01:30:02.000
definieren kannst die sich selbst referenzieren k wenn n Also wie JSON oder sowas zum Beispiel tats Zum Beispiel ja genau Also in JSON kann es ja auch sein dass du

01:30:02.000 --> 01:30:04.000
naja,

01:30:05.000 --> 01:30:06.000
schwierig.

01:30:06.000 --> 01:30:09.000
Ja, eine Liste von Objekten habe, in denen andere Listen stecken,

01:30:09.000 --> 01:30:10.000
die wieder irgendwie Toys haben oder so.

01:30:10.000 --> 01:30:13.000
Ja, genau. Oder in Array von Arrays.

01:30:13.000 --> 01:30:14.000
Ja.

01:30:14.000 --> 01:30:15.000
Wenn du dabei bist, ne.

01:30:16.000 --> 01:30:18.000
Ich habe mal mit jemandem

01:30:18.000 --> 01:30:19.000
vom TypeScript-Team gesprochen, bezüglich

01:30:19.000 --> 01:30:20.000
rekursiven Typen.

01:30:22.000 --> 01:30:24.000
das ist meistens ein Implementierungsdatei,

01:30:24.000 --> 01:30:26.000
wie tief der Compiler dort

01:30:26.000 --> 01:30:27.000
gehen kann. Also was sind die,

01:30:29.000 --> 01:30:30.000
wie ist

01:30:30.000 --> 01:30:31.000
der Compiler entwickelt,

01:30:31.000 --> 01:30:33.000
dass er bald genug sagen kann,

01:30:33.000 --> 01:30:35.000
hey, da stopp ich jetzt und passe nicht mehr weiter. Also wie

01:30:35.000 --> 01:30:37.000
geht der Compiler mit der Regression?

01:30:38.000 --> 01:30:39.000
Typsysteme können das eigentlich.

01:30:39.000 --> 01:30:41.000
Hat er auch in der IDE irgendwie, ich weiß nicht,

01:30:41.000 --> 01:30:43.000
bei JSON-Type oder sowas, bis wie viel Level

01:30:43.000 --> 01:30:45.000
tief darf der denn gucken,

01:30:46.000 --> 01:30:46.000
ob das noch stimmt?

01:30:47.000 --> 01:30:47.000
Genau.

01:30:49.000 --> 01:30:50.000
Und da werden sie auch immer besser.

01:30:50.000 --> 01:30:51.000
der Mathematik egal.

01:30:51.000 --> 01:30:56.000
Das ist der Mathematik egal, die guckt.

01:30:59.000 --> 01:31:01.000
Ja, genau.

01:31:02.000 --> 01:31:04.000
Ja, das kommt dann wieder

01:31:04.000 --> 01:31:05.000
darauf an, welche Art von Mathematik, wenn man

01:31:05.000 --> 01:31:08.000
den konstruktiven Zweig

01:31:08.000 --> 01:31:10.000
anhängt. Das gibt es gar nicht.

01:31:10.000 --> 01:31:10.000
Jason, das ist so schwierig.

01:31:12.000 --> 01:31:14.000
Wenn du schon in der Grundvorlesung,

01:31:15.000 --> 01:31:16.000
also ich habe ja

01:31:16.000 --> 01:31:18.000
eine mathematische Ausbildung genossen an der

01:31:18.000 --> 01:31:20.000
Universität, da werden dann die

01:31:20.000 --> 01:31:22.000
natürlichen Zahlen nochmal definiert und die werden rekursiv

01:31:22.000 --> 01:31:24.000
definiert. Da gibt es eigentlich nur eine natürliche Zahl,

01:31:24.000 --> 01:31:26.000
das ist die 0 oder die 1, je nachdem, wo du anfangen willst.

01:31:27.000 --> 01:31:27.000
Und dann

01:31:27.000 --> 01:31:30.000
sagt man einfach, jede Zahl hat einen Nachfolger

01:31:30.000 --> 01:31:32.000
und zack, hast du alle natürlichen Zahlen

01:31:32.000 --> 01:31:34.000
beisammen. Also es geht

01:31:34.000 --> 01:31:36.000
schon weit rein mit der Rekursion und

01:31:36.000 --> 01:31:38.000
die geht auch weit genug in der

01:31:38.000 --> 01:31:38.000
Mathematik.

01:31:40.000 --> 01:31:40.000
Ja.

01:31:41.000 --> 01:31:44.000
Ja, ich weiß nicht, haben wir noch,

01:31:44.000 --> 01:31:45.000
ah, was mir noch einfällt, genau.

01:31:46.000 --> 01:31:47.000
Das schließt so ein bisschen an das

01:31:47.000 --> 01:31:49.000
Pidentik-Thema von eben an.

01:31:50.000 --> 01:32:08.000
Ich meine, das ist ja jetzt etwas, die Typen werden ja zur Laufzeit ignoriert in Python, aber nicht immer und man müsste es auch nicht, weil im Grunde kann man rausfinden, wie die Annotationen sind und es gibt halt auch Software, die das macht, wie zum Beispiel Pydentic.

01:32:09.000 --> 01:32:10.000
Ja, oder MyPy.

01:32:10.000 --> 01:32:11.000
Oder FastAPI.

01:32:13.000 --> 01:32:14.000
Ja, genau.

01:32:15.000 --> 01:32:17.000
Gibt es sowas eigentlich in TypeScript auch?

01:32:18.000 --> 01:32:19.000
Weil ich meine, gut,

01:32:19.000 --> 01:32:21.000
das wird ja kompiliert zu JavaScript, aber es gibt ja jetzt auch

01:32:21.000 --> 01:32:23.000
glaube ich Interpreter,

01:32:23.000 --> 01:32:25.000
die direkt TypeScript interpretieren, so Deno

01:32:25.000 --> 01:32:27.000
oder sowas macht das glaube ich, ich weiß nicht so genau.

01:32:27.000 --> 01:32:28.000
Könnte das ja im Grunde dann tun.

01:32:29.000 --> 01:32:31.000
Das ist ja

01:32:31.000 --> 01:32:33.000
ein weitverbreiteter, ich glaube,

01:32:33.000 --> 01:32:35.000
dass Deno direkt TypeScript interpretiert.

01:32:35.000 --> 01:32:37.000
Deno hat nur einen TypeScript-Compiler

01:32:37.000 --> 01:32:39.000
inkludiert, also kompiliert TypeScript

01:32:39.000 --> 01:32:40.000
bevor er das JavaScript ausführt.

01:32:41.000 --> 01:32:42.000
Also tatsächlich,

01:32:42.000 --> 01:32:45.000
wie, also ich sage mal, im JavaScript-Bereich

01:32:45.000 --> 01:32:46.000
reden wir eher von unterschiedlichen

01:32:46.000 --> 01:32:48.000
Typsystemen, die existieren.

01:32:48.000 --> 01:32:51.000
Wie Flowtype ist zum Beispiel

01:32:51.000 --> 01:32:53.000
eins, das sehr, sehr optisch sehr, sehr ähnlich

01:32:53.000 --> 01:32:54.000
ist zu dem, was TypeScript

01:32:54.000 --> 01:32:56.000
zur Verfügung stellt, aber halt

01:32:56.000 --> 01:32:58.000
in den Nansen unterschiedlich ist.

01:32:58.000 --> 01:32:59.000
Oder eben TypeScript

01:32:59.000 --> 01:33:02.000
und das sind auch schon die populärsten.

01:33:02.000 --> 01:33:04.000
Der Clojure-Compiler hat einmal ähnlich funktioniert.

01:33:04.000 --> 01:33:06.000
Wie Typs definiert werden.

01:33:06.000 --> 01:33:06.000
Ja, CoffeeScript gab es früher.

01:33:07.000 --> 01:33:09.000
Ja, CoffeeScript ist aber sogar eine eigene Programmiersprache.

01:33:10.000 --> 01:33:12.000
Also wie Typs definiert werden,

01:33:12.000 --> 01:33:12.000
das meinen.

01:33:16.000 --> 01:33:17.000
Gleiche Historie.

01:33:19.000 --> 01:33:20.000
Ähnlich, ähnlich.

01:33:21.000 --> 01:33:22.000
Da gibt es auch einen wichtigen

01:33:22.000 --> 01:33:24.000
Punkt, weil wie Typen definiert werden

01:33:24.000 --> 01:33:26.000
in JavaScript, das ist ja eigentlich nicht

01:33:26.000 --> 01:33:28.000
dem TypeScript

01:33:28.000 --> 01:33:29.000
Team zu verdanken, sondern

01:33:29.000 --> 01:33:32.000
dem ECMAScript 4 Standard, der schon

01:33:32.000 --> 01:33:34.000
viel, viel älter ist,

01:33:34.000 --> 01:33:36.000
der nie umgesetzt wurde, an den

01:33:36.000 --> 01:33:38.000
sich aber alle Typsysteme jetzt irgendwie dranhalten

01:33:38.000 --> 01:33:40.000
bei der Definition des eigenen Typsystems.

01:33:40.000 --> 01:33:42.000
Ich würde eher sogar sagen, dass

01:33:42.000 --> 01:33:45.000
Action-Skript, also die Flash-Programmiersprache

01:33:45.000 --> 01:33:46.000
noch eher

01:33:46.000 --> 01:33:48.000
ähnlicher oder verwandter mit

01:33:48.000 --> 01:33:49.000
TypeScript und Flow-Type ist.

01:33:51.000 --> 01:33:52.000
Aber

01:33:52.000 --> 01:33:54.000
das ist es dann auch. Also du

01:33:54.000 --> 01:33:56.000
hast entweder unterschiedliche Typsysteme,

01:33:56.000 --> 01:33:58.000
dann entscheidest du dich in den meisten Fällen

01:33:58.000 --> 01:34:00.000
heutzutage eh für TypeScript und dann

01:34:00.000 --> 01:34:02.000
bietet dir TypeScript eigentlich alles, was du dafür

01:34:02.000 --> 01:34:03.000
brauchst. Also du

01:34:03.000 --> 01:34:06.000
laufst dir gar nicht in Gefahr, dass du

01:34:06.000 --> 01:34:06.000
irgendwie

01:34:06.000 --> 01:34:10.000
ein anderes Werkzeug nimmst.

01:34:10.000 --> 01:34:27.000
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, dass du sagst, hey, ich weiß jetzt, welche Typen du verwendest, rein in der Verwendung deines Codes.

01:34:27.000 --> 01:34:46.000
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 TypeScape TypeChecker eh gut genug ist, dass er schon sehr, sehr viel herausfindet, bevor du überhaupt irgendeine Annotation machen musst.

01:34:46.000 --> 01:34:48.000
was

01:34:48.000 --> 01:34:50.000
ein gutes Migrations-Solid ist

01:34:50.000 --> 01:35:02.000
ist JS das ist halt ein Typ im Kommentar wo du einfach sagst hey du hast diese Funktion die hat drei Parameter du definierst den Typen im Kommentar

01:35:02.000 --> 01:35:04.000
und nicht im Code.

01:35:05.000 --> 01:35:06.000
Und das machen viele Bibliotheken,

01:35:06.000 --> 01:35:09.000
das machen sehr viele alte JavaScript-Bibliotheken,

01:35:09.000 --> 01:35:12.000
wie zum Beispiel Lodesh oder Underscore schon.

01:35:13.000 --> 01:35:14.000
Und TypeScript kann mit dem umgehen.

01:35:14.000 --> 01:35:17.000
Also TypeScript kann auch Typ-Informationen aus diesen Kommentaren lesen

01:35:17.000 --> 01:35:23.000
und hat halt so weit mehr Kompatibilität mit dem gesamten Ökosystem,

01:35:23.000 --> 01:35:26.000
als wenn sie darauf bestehen würden, dass sie nur die Typen verwenden, die du annotierst.

01:35:29.000 --> 01:35:34.000
Okay, aber so ein richtiges Äquivalent zu dem, was der Jochen gefragt oder gesagt hat,

01:35:34.000 --> 01:35:35.000
gibt es nicht wirklich.

01:35:35.000 --> 01:35:38.000
Zur Laufzeit hast du nicht wirklich mehr die Typinformation.

01:35:38.000 --> 01:35:55.000
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. Es gibt auch ein paar Reflection-Geschichten.

01:35:55.000 --> 01:35:57.000
Also okay, dass du so rumgehst.

01:35:57.000 --> 01:36:14.000
Das ist aber alles Mumpitz. Das möchte ich nicht einmal erwähnen, weil es einfach Schwachsinn ist. Eine Sache, die aber gut ist, zum Beispiel dieses SOD, wenn du jetzt sagst, du brauchst jetzt Typinformationen zu Laufzeit auch, dann kannst du über die SOD-Bibliothek dir deinen Typen in JavaScript definieren.

01:36:14.000 --> 01:36:32.000
Das ist aber nicht TypeScript, das ist JavaScript. Und kannst dann, wenn du diesen Typen weiter im TypeScript-Code verwenden willst, sagen, hey, leite mir jetzt aus diesem JavaScript-Konstrukt, das ich gebaut habe, das einen Typen darstellen soll, leite mir von diesem JavaScript-Konstrukt doch einen TypeScript-Typen ab, den ich weiterverwende.

01:36:32.000 --> 01:36:35.000
und du bekommst dann zum einen einen Typ,

01:36:35.000 --> 01:36:38.000
klassischer TypeScript-Typ,

01:36:38.000 --> 01:36:40.000
den du in deinen Methodensignaturen verwenden kannst,

01:36:40.000 --> 01:36:42.000
den du annotieren kannst,

01:36:42.000 --> 01:36:44.000
wo du Typechecken hast,

01:36:44.000 --> 01:36:45.000
das funktioniert, das ist grandios gut.

01:36:46.000 --> 01:36:48.000
Parallel dazu hast du immer noch dieses JavaScript-Konstrukt

01:36:48.000 --> 01:36:49.000
mit der ersten Validierung empfangen kannst.

01:36:49.000 --> 01:36:50.000
Das heißt, du kannst sagen,

01:36:50.000 --> 01:36:52.000
hey, du kriegst jetzt ein Chasen von einem Backend,

01:36:53.000 --> 01:36:55.000
steckst es in den Validator rein

01:36:55.000 --> 01:36:56.000
und kriegst entweder Ergebnisse,

01:36:56.000 --> 01:36:57.000
die es nachher dem Typen entspricht, super,

01:36:58.000 --> 01:36:59.000
oder Fehlermeldungen, mit denen du umgehen kannst.

01:36:59.000 --> 01:37:03.000
und das ist eine grandiose Bibliothek.

01:37:05.000 --> 01:37:07.000
Erstens ist sie so nah an TypeScript,

01:37:07.000 --> 01:37:08.000
dass du wirklich sämtliche Dinge,

01:37:08.000 --> 01:37:10.000
die du in TypeScript schreiben kannst,

01:37:10.000 --> 01:37:12.000
auch damit umsetzen kannst.

01:37:12.000 --> 01:37:13.000
Und zweitens ist sie schnell,

01:37:14.000 --> 01:37:15.000
sie macht robusteren Code.

01:37:15.000 --> 01:37:16.000
Ich bin total glücklich mit der,

01:37:17.000 --> 01:37:18.000
die kann ich sehr, sehr gut empfehlen.

01:37:18.000 --> 01:37:18.000
Also unbedingt.

01:37:19.000 --> 01:37:20.000
Aber prinzipiell gilt es.

01:37:20.000 --> 01:37:21.000
Okay, cool.

01:37:21.000 --> 01:37:23.000
Also ein ähnliches Verfahren.

01:37:23.000 --> 01:37:23.000
Sehr ähnlich.

01:37:23.000 --> 01:37:25.000
In SORT ist es aber so,

01:37:25.000 --> 01:37:29.000
dass du die Typen dann anfängst zu schreiben

01:37:29.000 --> 01:37:31.000
in dieser JavaScript-Welt

01:37:31.000 --> 01:37:36.000
mit den dort vorhandenen Methoden und Funktionen.

01:37:36.000 --> 01:37:37.000
Und das ist halt umgekehrt zu dem,

01:37:37.000 --> 01:37:39.000
was du normalerweise in TypeScript hast,

01:37:39.000 --> 01:37:41.000
dass du sagst, du schreibst deine Typen

01:37:41.000 --> 01:37:42.000
und die sind nach dem Kompilator einfach weg.

01:37:42.000 --> 01:37:45.000
Also TypeScript ist so eine Erased-to-JavaScript-Sprache,

01:37:46.000 --> 01:37:48.000
was auch bedeutet, wenn du die zur Laufzeit haben willst,

01:37:48.000 --> 01:37:49.000
musst du in JavaScript anfangen

01:37:49.000 --> 01:37:50.000
und musst halt dem anderen weggehen.

01:37:52.000 --> 01:37:53.000
Ja, okay, aber da steht ja nicht,

01:37:53.000 --> 01:37:56.000
würde ja nicht prinzipiell was dagegen sprechen, oder?

01:37:56.000 --> 01:37:59.000
Dass du von TypeScript-Typen zu JavaScript-Typen gehst.

01:37:59.000 --> 01:38:01.000
ist nur jetzt halt das Tooling, das

01:38:01.000 --> 01:38:03.000
existiert nicht. Ja, okay, aber das war cool.

01:38:03.000 --> 01:38:05.000
Also du hast auf jeden Fall das Gleiche. Unbedingt zu empfehlen.

01:38:06.000 --> 01:38:07.000
Ja, unbedingt

01:38:07.000 --> 01:38:08.000
zu empfehlen. Also das ist richtig, richtig cool.

01:38:08.000 --> 01:38:11.000
Finde ich super spannend. Könnte auch für mich nützlich sein.

01:38:12.000 --> 01:38:13.000
Also gerade wenn du

01:38:13.000 --> 01:38:15.000
mit Backends arbeiten musst,

01:38:15.000 --> 01:38:16.000
denen du nicht trauen kannst, herrlich.

01:38:17.000 --> 01:38:18.000
Ja, oder mit

01:38:18.000 --> 01:38:20.000
Inputs von Benutzern. Ich meine,

01:38:21.000 --> 01:38:22.000
da musst du eh immer Validierung machen, aber das

01:38:22.000 --> 01:38:24.000
kann einem ja

01:38:24.000 --> 01:38:27.000
in dem Sinne die Arbeit ein bisschen abnehmen.

01:38:27.000 --> 01:38:30.000
Naja, also man definiert halt, wie man gerne hätte,

01:38:30.000 --> 01:38:32.000
dass die eigene Datenstruktur aussieht

01:38:32.000 --> 01:38:35.000
und benutzt dann diese Information halt auch zur Validierung dagegen.

01:38:35.000 --> 01:38:37.000
Das ist natürlich, also ja,

01:38:37.000 --> 01:38:40.000
das ist genau eigentlich der Use Case von Pydentic auch.

01:38:42.000 --> 01:38:42.000
Ja, ja.

01:38:42.000 --> 01:38:44.000
Muss man das Pydentic noch genau anschauen.

01:38:44.000 --> 01:38:46.000
Also das hört sich zum Zeitmehr,

01:38:46.000 --> 01:38:48.000
ich habe es heute gehört, wie wir begonnen haben.

01:38:50.000 --> 01:38:50.000
Und jetzt wieder.

01:38:51.000 --> 01:38:51.000
Erklär mal, Jochen,

01:38:51.000 --> 01:38:54.000
erzähl mal den Unterschied zwischen FastAPI und Pydentic.

01:38:54.000 --> 01:38:58.000
Ach ja, FastAPI ist sozusagen ein ...

01:38:58.000 --> 01:38:59.000
Ein Repetaface fast.

01:38:59.000 --> 01:39:01.000
Ja, genau.

01:39:02.000 --> 01:39:02.000
Automatisierung bereitgestellt.

01:39:02.000 --> 01:39:03.000
Und Pidentic?

01:39:03.000 --> 01:39:06.000
Pidentic ist eine Bibliothek, die benutzt wird von FastAPI.

01:39:07.000 --> 01:39:14.000
Und die halt sozusagen ermöglicht, wenn man halt mit Typannotationen sozusagen oder der Syntax ...

01:39:14.000 --> 01:39:18.000
Es gibt noch mehr, weil man kann halt auch noch mehr machen als nur die Sachen, die mit Annotationen möglich sind.

01:39:18.000 --> 01:39:45.000
Man kann halt auch Validierungsfunktionen haben und Upper Limits und Lower Limits und weiß ich nicht, ganz viel kompliziertes Zeugs halt auch mit dazu schreiben. Das geht mit den Typannotationen natürlich nicht, aber wenn man einfach nur die Typannotationen hinschreibt, dann passiert das halt auch, dass dann sozusagen man JSON nehmen kann und man hat halt eine Objektstruktur definiert mit den Typen und dann sagt man halt, hier ist das JSON, passt das mal und validiert das mal.

01:39:45.000 --> 01:39:47.000
Genau, und wenn es nicht, dann kriegst du 4-2-2 zurück,

01:39:47.000 --> 01:39:48.000
weil da fehlt irgendwas.

01:39:48.000 --> 01:39:51.000
Wenn es nicht okay ist, kriegt man halt schöne Fehlermeldungen

01:39:51.000 --> 01:39:53.000
auch zurück, wo dann genau gesagt wird,

01:39:53.000 --> 01:39:55.000
so an der Stelle hast du gesagt,

01:39:55.000 --> 01:39:56.000
das soll ein Number sein, aber

01:39:56.001 --> 01:39:57.000
da ist ein String oder

01:39:57.000 --> 01:39:59.000
das ist halt irgendwie, das passt sonst wie nicht.

01:39:59.000 --> 01:40:01.000
Das soll eine Liste sein, aber das ist halt nicht.

01:40:02.000 --> 01:40:03.000
Ja, und das ist natürlich nett.

01:40:03.000 --> 01:40:05.000
Also es ist quasi

01:40:05.000 --> 01:40:07.000
das, woraus

01:40:07.000 --> 01:40:09.000
FastAPI gebaut wird. FastAPI ist

01:40:09.000 --> 01:40:11.000
identisch via

01:40:11.000 --> 01:40:12.000
HTTP.

01:40:13.000 --> 01:40:15.000
Ja, plus es sind noch so ein paar

01:40:15.000 --> 01:40:17.000
Sachen zusätzlich dabei.

01:40:17.000 --> 01:40:19.000
Starlet ist halt irgendwie sozusagen das alles, was

01:40:19.000 --> 01:40:21.000
HTTP angeht oder so, macht

01:40:21.000 --> 01:40:23.000
darunter, die Bibliothek von Tom Christie.

01:40:24.000 --> 01:40:25.000
Also FastAPI ist schon so ein bisschen

01:40:25.000 --> 01:40:27.000
ist halt so irgendwie

01:40:27.000 --> 01:40:29.000
drei sehr coole oder drei, vier

01:40:29.000 --> 01:40:31.000
sehr coole Open-Source-Bibliotheken in einem French-Code

01:40:31.000 --> 01:40:33.000
irgendwie quasi. Noch so Routing

01:40:33.000 --> 01:40:35.000
das hat man halt irgendwie von

01:40:35.000 --> 01:40:37.000
Flass früher kannte, als Dekorator oben

01:40:37.000 --> 01:40:38.000
an der Route dran.

01:40:38.000 --> 01:40:40.000
Ja genau, das ist natürlich auch sehr alt.

01:40:41.000 --> 01:40:42.000
Also Stefan, wenn du

01:40:42.000 --> 01:40:44.000
FastAP schon kennst, dann weißt du auch

01:40:44.000 --> 01:40:46.000
wie Pedantic funktioniert, nur halt innerhalb.

01:40:46.000 --> 01:40:46.000
Okay.

01:40:48.000 --> 01:40:50.000
Also wie gesagt, ich habe den Namen in

01:40:50.000 --> 01:40:52.000
Architektur-Diagramm geschrieben, also das ist

01:40:52.000 --> 01:40:53.000
meine Erfahrung damit, aber

01:40:53.000 --> 01:40:55.000
reicht anscheinend.

01:40:56.000 --> 01:40:57.000
Ist schon mehr damit gemacht als viele andere.

01:40:59.000 --> 01:41:00.000
Genau.

01:41:00.000 --> 01:41:01.000
Ja.

01:41:02.000 --> 01:41:04.000
Genau, also ja, das ist auf jeden Fall

01:41:04.000 --> 01:41:05.000
auch so noch ein ganz interessanter Ding,

01:41:05.000 --> 01:41:08.000
weil ich meine, das ist ja tatsächlich so, wie viele Leute

01:41:08.000 --> 01:41:09.000
das benutzen. Viele Leute benutzen dann einen TypeDict

01:41:09.000 --> 01:41:11.000
und denken, das würde passieren, dass es validiert wird,

01:41:11.000 --> 01:41:12.000
aber es passiert halt nicht.

01:41:13.000 --> 01:41:15.000
Ja, genau.

01:41:16.000 --> 01:41:17.000
Ja, ansonsten, ich weiß es nicht. Haben wir noch irgendwas

01:41:17.000 --> 01:41:19.000
Großes vergessen oder so? Aber ich glaube,

01:41:20.000 --> 01:41:21.000
ansonsten, ich habe hier

01:41:21.000 --> 01:41:23.000
fast nichts mehr, was ich noch irgendwie unbedingt

01:41:23.000 --> 01:41:25.000
gerne wissen wollte.

01:41:25.000 --> 01:41:28.000
Ja, nach anderthalb Stunden

01:41:28.000 --> 01:41:29.000
alles über

01:41:29.000 --> 01:41:31.000
Typsysteme und Typen gesagt.

01:41:32.000 --> 01:41:33.000
Das ging ja relativ schnell jetzt.

01:41:34.000 --> 01:41:34.000
Ja.

01:41:35.000 --> 01:41:37.000
Für meinen Typen habt ihr immer noch keine Erklärung gefunden, aber sonst.

01:41:38.000 --> 01:41:38.000
Ja.

01:41:40.000 --> 01:41:41.000
So Typen wie dich, Dominik,

01:41:42.000 --> 01:41:42.000
ist schwer zu beschreiben.

01:41:42.000 --> 01:41:43.000
Das ist so.

01:41:44.000 --> 01:41:44.000
Ja.

01:41:46.000 --> 01:41:48.000
So, ja.

01:41:49.000 --> 01:41:50.000
Wirklich, ich finde es schön.

01:41:50.000 --> 01:41:52.000
Stefan, hast du noch was, was du unbedingt loswerden

01:41:52.000 --> 01:41:54.000
wolltest? Ich glaube, ich habe jetzt noch

01:41:54.000 --> 01:41:56.000
ein anschauliches Beispiel gefunden zu

01:41:56.000 --> 01:41:58.000
Co-Varianz und Kontra-Varianz, nachdem ich mir

01:41:58.000 --> 01:42:00.000
die Grafik so lange angeschaut habe. Ich hoffe, ich kann es erklären.

01:42:02.000 --> 01:42:02.000
Co-Varianz

01:42:02.000 --> 01:42:04.000
ist in Wirklichkeit, was

01:42:04.000 --> 01:42:06.000
wir als Subtyping

01:42:06.000 --> 01:42:08.000
verstehen. Angenommen, du hast ein Lebewesen,

01:42:08.000 --> 01:42:10.000
dann hast du ein Subtyp davon, das ist ein

01:42:10.000 --> 01:42:12.000
Pflanzenfresser, dann hast du ein Subtyp davon, das

01:42:12.000 --> 01:42:14.000
ist eine Kuh. Das heißt, du wirst immer konkreter und konkreter

01:42:14.000 --> 01:42:16.000
und konkreter. Was bedeutet, wenn

01:42:16.000 --> 01:42:18.000
du irgendwo ein Lebewesen erwartest, kannst du dort

01:42:18.000 --> 01:42:20.000
einen Pflanzenfresser reinschmeißen, kannst aber auch Kühe

01:42:20.000 --> 01:42:22.000
reinschmeißen oder Schafe reinschmeißen oder

01:42:22.000 --> 01:42:25.000
Veganer.

01:42:25.000 --> 01:42:26.000
Von mir aus, ne?

01:42:27.000 --> 01:42:29.000
Und das ist Co-Varianz.

01:42:29.000 --> 01:42:31.000
Das heißt, du kannst

01:42:31.000 --> 01:42:33.000
etwas sehr Breites akzeptieren

01:42:33.000 --> 01:42:35.000
und kannst was sehr Konkretes reinstopfen,

01:42:35.000 --> 01:42:36.000
wenn der Subtyp...

01:42:36.000 --> 01:42:39.000
Das heißt, ich erwarte ein Lebewesen als Type Annotation quasi.

01:42:40.000 --> 01:42:40.000
Genau, genau, genau.

01:42:41.000 --> 01:42:43.000
Jetzt hast du aber zum Beispiel

01:42:43.000 --> 01:42:45.000
eine andere Co-Varianz,

01:42:45.000 --> 01:42:47.000
nämlich du hast jetzt Pflanze und davon

01:42:47.000 --> 01:42:49.000
abgeleitet Gras und davon

01:42:49.000 --> 01:43:03.000
abgeleitet vielleicht Heu oder so Und jetzt willst du eine Funktion zur Verf stellen die akzeptiert Grasesser dann kannst du dort bei den Grasessern K aber auch Pflanzenfresser reinschmei

01:43:03.000 --> 01:43:25.000
Wenn du jetzt aber sagst, du akzeptierst jetzt Pflanzen, also alle die Pflanzen oder Funktionen von Entitäten, die alle Pflanzen essen können, dann kannst du dort keine Kühe reingeben, weil Kühe können nur Gras essen.

01:43:26.000 --> 01:43:27.000
Und das ist Kontrovarianz.

01:43:27.000 --> 01:43:29.000
Das heißt, du hast zwar auch einen Subtypen,

01:43:29.000 --> 01:43:31.000
du hast einen sehr breiten Typen. Ich akzeptiere

01:43:31.000 --> 01:43:33.000
ja Pflanzenfresser. Allerdings

01:43:33.000 --> 01:43:35.000
kannst du keine Kühe reingeben, weil Kühe nur Gras

01:43:35.000 --> 01:43:35.000
essen dürfen.

01:43:37.000 --> 01:43:39.000
Und Invarianz ist dann ganz festgesetzt, dass

01:43:39.000 --> 01:43:41.000
nur den einen speziellen Typ. Genau, Invarianz ist

01:43:41.000 --> 01:43:42.000
die beiden Richtungen.

01:43:43.000 --> 01:43:45.000
Also ich hoffe, dass das nochmal

01:43:45.000 --> 01:43:47.000
veranschaulicht. Ich glaube, wir gucken

01:43:47.000 --> 01:43:49.000
lieber dein Bild nochmal an. Ich hoffe, das Bild ist so

01:43:49.000 --> 01:43:51.000
anschaulich für die Leute,

01:43:51.000 --> 01:43:52.000
die ausgestiegen sind.

01:43:53.000 --> 01:43:55.000
Ja, super.

01:43:55.000 --> 01:43:57.000
Da wir sicherlich ganz viele E-Mails kriegen und das in den

01:43:57.000 --> 01:43:58.000
nächsten vier Folgen alles nochmal

01:43:58.000 --> 01:44:00.000
präsentieren.

01:44:00.000 --> 01:44:03.000
Ist ja auch okay, wenn da eine Erklärung dabei ist.

01:44:04.000 --> 01:44:05.000
Hallo, jetzt peistenpodcast.de

01:44:05.000 --> 01:44:07.000
Wir haben aber noch

01:44:07.000 --> 01:44:09.000
gar nicht ganz fertig, weil wir möchten

01:44:09.000 --> 01:44:11.000
noch unseren Pick der Woche, glaube ich,

01:44:11.000 --> 01:44:12.000
auswählen.

01:44:12.000 --> 01:44:13.000
Ich fange mal an.

01:44:14.000 --> 01:44:16.000
Stefan, weißt du denn, was ein Pick ist?

01:44:17.000 --> 01:44:19.000
Ja, also müssen wir jetzt irgendeinen Link raussuchen,

01:44:19.000 --> 01:44:20.000
den er total grandios findet.

01:44:20.000 --> 01:44:20.000
Ja, genau.

01:44:21.000 --> 01:44:22.000
Irgendwas Schönes.

01:44:23.000 --> 01:44:25.000
Meistens haben wir Python-Module, aber

01:44:25.000 --> 01:44:27.000
ich nehme tatsächlich, ja auch nicht immer,

01:44:28.000 --> 01:44:29.000
ich nehme tatsächlich diesmal eins

01:44:29.000 --> 01:44:31.000
von Simon Willison und zwar das LLM.

01:44:31.000 --> 01:44:33.000
Ich glaube, das haben wir bei einer der Machine Learning Folgen

01:44:33.000 --> 01:44:35.000
das Kommandozeilentool.

01:44:35.000 --> 01:44:38.000
Das war schon in Shownotes irgendwo gehabt, aber es ist tatsächlich

01:44:38.000 --> 01:44:40.000
bei mir ist es vermehrt in Benutzung.

01:44:40.000 --> 01:44:41.000
Im Monkey Patch schon immer das Default,

01:44:41.000 --> 01:44:43.000
aber sonst ist es sehr, sehr schön, weil du

01:44:43.000 --> 01:44:45.000
halt ganz viele Templates und

01:44:45.000 --> 01:44:47.000
Chains von Templates direkt benutzen kannst

01:44:47.000 --> 01:44:49.000
in deiner Kommandozeile, um halt

01:44:49.000 --> 01:44:51.000
mit den verschiedenen Modellen zu sprechen,

01:44:51.000 --> 01:44:53.000
direkt, die du da haben willst.

01:44:53.000 --> 01:44:56.000
und es ist toll, wenn man

01:44:56.000 --> 01:44:57.000
harte Instruktionen gibt, dann so die

01:44:57.000 --> 01:45:00.000
Standard-Persönlichkeit des

01:45:00.000 --> 01:45:02.000
antwortenden LLMs

01:45:02.000 --> 01:45:04.000
irgendwie so ein bisschen gerade

01:45:04.000 --> 01:45:06.000
zu rücken auf das, was man selber gerne als Antwort

01:45:06.000 --> 01:45:06.000
hätte.

01:45:08.000 --> 01:45:10.000
Such dir die Leute genug gut

01:45:10.000 --> 01:45:12.000
aus, mit denen du sprichst, das wollte ich damit sagen

01:45:12.000 --> 01:45:14.000
und deswegen

01:45:14.000 --> 01:45:16.000
viel Spaß. Und dann lädst du uns ein, Dominik.

01:45:17.000 --> 01:45:18.000
Weiterhin viel Spaß

01:45:18.000 --> 01:45:20.000
bei den nächsten Picks, wollte ich noch sagen.

01:45:22.000 --> 01:45:22.000
Ja.

01:45:23.000 --> 01:45:24.000
Ja, was hast du denn geblickt, Jochen?

01:45:25.000 --> 01:45:27.000
Was wollte ich? Ah, genau, ich dachte

01:45:27.000 --> 01:45:29.000
mir so, naja, vielleicht auch ein Buch mal.

01:45:30.000 --> 01:45:31.000
Und zwar eins, das ich nicht gelesen

01:45:31.000 --> 01:45:33.000
habe. Aber wo man

01:45:33.000 --> 01:45:35.000
das alles nachlesen kann, kann man auch

01:45:35.000 --> 01:45:37.000
die Antworten, wenn man

01:45:37.000 --> 01:45:39.000
drauf gekommen ist, wie das sein muss, an uns schicken.

01:45:40.000 --> 01:45:41.000
Und zwar The Little

01:45:41.000 --> 01:45:43.000
Typer ist ein Buch, das

01:45:43.000 --> 01:45:45.000
ich habe es versucht zu lesen, es ist irgendwie, ich habe

01:45:45.000 --> 01:45:46.000
dann zwischendurch aufgegeben.

01:45:47.000 --> 01:46:00.000
Das muss ich sagen wie Experiment mit Types entbei Ja Aber da steht da steht das glaube ich alles ganz genau drin wenn man das wissen will Und vielleicht nochmal was Praktisches weil ja

01:46:01.000 --> 01:46:01.000
das ist ja doch nicht

01:46:01.000 --> 01:46:04.000
für alle wahrscheinlich.

01:46:05.000 --> 01:46:06.000
Doku ist ganz nett,

01:46:06.000 --> 01:46:08.000
auch nicht Python, sondern

01:46:08.000 --> 01:46:10.000
Go. Geschichte,

01:46:11.000 --> 01:46:12.000
Heroku hatte ja in letzter Zeit

01:46:12.000 --> 01:46:14.000
so ein bisschen Probleme und

01:46:14.000 --> 01:46:16.000
ist nicht mehr

01:46:16.000 --> 01:46:18.000
so richtig der Platz, wo man vielleicht

01:46:18.000 --> 01:46:20.000
so mal so, wenn man, also früher hat man das ja

01:46:20.000 --> 01:46:21.000
irgendwie mal irgendwas mal eben

01:46:21.000 --> 01:46:24.000
deployen wollte, hat man das oft dann bei Heroku

01:46:24.000 --> 01:46:26.000
oder so getan, weil das halt

01:46:26.000 --> 01:46:27.000
sehr einfach war, aber das

01:46:27.000 --> 01:46:29.000
geht irgendwie nicht mehr.

01:46:30.000 --> 01:46:32.000
Und das kann man auch im Selbstmodus...

01:46:32.000 --> 01:46:33.000
Wo würdest du das jetzt machen, Jochen?

01:46:33.000 --> 01:46:36.000
Also meine Lösung dafür ist ja, dass ich

01:46:36.000 --> 01:46:38.000
das halt einfach, ich hab da so meine Standard

01:46:38.000 --> 01:46:40.000
Ansible...

01:46:40.000 --> 01:46:41.000
Ja, okay, gut. Also du

01:46:41.000 --> 01:46:44.000
bist vom, dir ist

01:46:44.000 --> 01:46:46.000
Heroku zu kompliziert geworden und

01:46:46.000 --> 01:46:48.000
deshalb hast du jetzt deine eigene Hosting-Lösung

01:46:48.000 --> 01:46:50.000
gebaut, aber das ist

01:46:50.000 --> 01:46:51.000
natürlich keine Option, die jetzt viele

01:46:51.000 --> 01:46:54.000
dazu haben. Genau, also das kann ich auch nicht unbedingt

01:46:54.000 --> 01:46:56.000
empfehlen, das ist das unerwartet

01:46:56.000 --> 01:46:57.000
kompliziert, aber

01:46:57.000 --> 01:47:00.000
bei mir geht's jetzt daher, hab ich das Problem nicht mehr.

01:47:00.000 --> 01:47:02.000
Und ich mach ja auch kein Docker oder so,

01:47:02.000 --> 01:47:03.000
sondern ich deploye dann direkt

01:47:03.000 --> 01:47:04.000
irgendwie

01:47:04.000 --> 01:47:08.000
Knallerhart, Bare Metal. Ja, genau.

01:47:09.000 --> 01:47:09.000
Und

01:47:09.000 --> 01:47:12.000
bei Doku

01:47:12.000 --> 01:47:14.000
hat man dann halt irgendwie sowas, wo man

01:47:14.000 --> 01:47:15.000
dann so ähnlich wie mit Heroku einfach, man

01:47:15.000 --> 01:47:18.000
hat halt so ein POC-File und dann kann man das einfach

01:47:18.000 --> 01:47:20.000
direkt und da auch, also wenn man

01:47:20.000 --> 01:47:22.000
einen Docker-Container bauen kann, kann man direkt Docker-Container

01:47:22.000 --> 01:47:24.000
dahin deployen und die laufen dann unter

01:47:24.000 --> 01:47:26.000
Subdomain direkt mit HTTPS und so.

01:47:26.000 --> 01:47:28.000
Arbeitet das sogar mit Heroku, also Doku?

01:47:29.000 --> 01:47:30.000
Äh, nee, nee, das ist

01:47:30.000 --> 01:47:32.000
also, aber du musst halt das Doku

01:47:32.000 --> 01:47:34.000
auf einem von, von, von

01:47:34.000 --> 01:47:36.000
irgendwo auf einem, weiß ich nicht, auf einer

01:47:36.000 --> 01:47:38.000
virtuellen Maschine, irgendeinem

01:47:38.000 --> 01:47:40.000
Dings halt deployed haben. Achso, ein self-hosted

01:47:40.000 --> 01:47:42.000
Heroku. Genau, self-hosted Heroku

01:47:42.000 --> 01:47:43.000
quasi. Genau.

01:47:43.000 --> 01:47:46.000
und genau, das ist glaube ich manchmal ganz

01:47:46.000 --> 01:47:47.000
hilfreich, sowas zu haben.

01:47:49.000 --> 01:47:49.000
Okay, dann

01:47:49.000 --> 01:47:52.000
schließe ich mich da direkt mal an, weil

01:47:52.000 --> 01:47:53.000
in dem Fall habe ich drei Picks.

01:47:55.000 --> 01:47:56.000
Der erste

01:47:56.000 --> 01:47:57.000
ist Vercel.

01:47:58.000 --> 01:48:00.000
Das ist wie

01:48:00.000 --> 01:48:01.000
Heroku nur cooler.

01:48:02.000 --> 01:48:04.000
Der zweite wäre

01:48:04.000 --> 01:48:06.000
Fly.io. Das ist quasi

01:48:06.000 --> 01:48:08.000
Docker-Sachen

01:48:08.000 --> 01:48:10.000
auf Hosted-Infrastruktur überall hin

01:48:10.000 --> 01:48:12.000
machen und die

01:48:12.000 --> 01:48:13.000
machen krasses technisches Zeugs damit. Also du

01:48:13.000 --> 01:48:16.000
schickst dir den Docker-Container, aber die zerlegen

01:48:16.000 --> 01:48:17.000
den und

01:48:17.000 --> 01:48:19.000
bauen sich da eigene Sachen draus.

01:48:20.000 --> 01:48:22.000
Das ist auch technologisch sehr interessant.

01:48:23.000 --> 01:48:24.000
Das war jetzt aber

01:48:24.000 --> 01:48:25.000
der opportunistische Pick,

01:48:26.000 --> 01:48:27.000
nur um da die

01:48:27.000 --> 01:48:30.000
Alternativen zu Heroku und

01:48:30.000 --> 01:48:32.000
Self-Hosted einmal gesagt zu haben.

01:48:32.000 --> 01:48:34.000
Hier sind wir ganz tief in den Pop-Bretchen.

01:48:35.000 --> 01:48:35.000
Genau.

01:48:36.000 --> 01:48:38.000
Mein eigentlicher Pick ist was ganz anderes.

01:48:38.000 --> 01:48:39.000
Und zwar,

01:48:39.000 --> 01:48:42.000
das ZDF hat ja eine Mediathek

01:48:42.000 --> 01:48:44.000
und auf dieser Mediathek kann man

01:48:44.000 --> 01:48:45.000
Sachen ansehen und wenn man ein paar Sachen angesehen hat,

01:48:46.000 --> 01:48:48.000
dann versucht das ZDF da Recommendations

01:48:48.000 --> 01:48:57.000
draus zu machen Wow das ist das erste Mal seit Ewigkeiten dass ich von Fernsehen etwas h Du meinst das ZDF meinst du das tats Fernsehen Ja

01:48:59.000 --> 01:49:01.000
Das zweite

01:49:01.000 --> 01:49:02.000
deutsche Fernsehen, meine ich.

01:49:04.000 --> 01:49:05.000
Und die,

01:49:05.000 --> 01:49:06.000
also nur die Mediathek.

01:49:08.000 --> 01:49:09.000
Und weil das

01:49:09.000 --> 01:49:11.000
ZDF ja in öffentlich-rechtlicher Hand ist,

01:49:11.000 --> 01:49:13.000
haben die sich gesagt, eigentlich müssen wir das ja den Leuten

01:49:13.000 --> 01:49:15.000
zurückgeben. Und das haben sie tatsächlich gemacht.

01:49:15.000 --> 01:49:16.000
Die haben ihr Recommendation-System

01:49:16.000 --> 01:49:19.000
auf GitHub gepackt.

01:49:19.000 --> 01:49:20.000
Und man kann das jetzt ansehen.

01:49:21.000 --> 01:49:23.000
GitHub ZDF minus Open Source.

01:49:24.000 --> 01:49:25.000
Gibt es auch jetzt schon

01:49:25.000 --> 01:49:27.000
ein Repository drunter. Das heißt

01:49:27.000 --> 01:49:28.000
Recommendations PA Base.

01:49:29.000 --> 01:49:31.000
Und da sind,

01:49:31.000 --> 01:49:33.000
da ist das Recommendations System

01:49:33.000 --> 01:49:34.000
vom ZDF drin. Und fand ich einfach spannend,

01:49:35.000 --> 01:49:37.000
das mal anzusehen.

01:49:37.000 --> 01:49:39.000
Weil da ja doch auch einiges

01:49:39.000 --> 01:49:41.000
an Arbeit drin steckt. Und weil es da auch

01:49:41.000 --> 01:49:43.000
viele Firmen gibt, die sowas gerne hätten.

01:49:46.000 --> 01:49:50.000
Genau, das war's von mir. Stefan, hast du noch was für uns dabei?

01:49:50.000 --> 01:50:05.000
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:05.000 --> 01:50:09.000
und das ist sehr spannend, weil er versucht zu erklären

01:50:09.000 --> 01:50:11.000
anhand von Farben,

01:50:13.000 --> 01:50:17.000
wie sich normale Funktionen und asynchrone Funktionen

01:50:17.000 --> 01:50:19.000
im Sprachdesign unterscheiden.

01:50:19.000 --> 01:50:22.000
Also rein aus der Perspektive von,

01:50:22.000 --> 01:50:24.000
welche Herausforderungen kriegst du als Sprachdesigner,

01:50:24.000 --> 01:50:27.000
wenn du so ein Asian-Greed-Konstrukt gestalten musst.

01:50:28.000 --> 01:50:30.000
Und wie gesagt, der ist schon ewig alt,

01:50:30.000 --> 01:50:33.000
aber er ist vor kurzem wieder bei uns in der Firma aufgeprobt.

01:50:33.000 --> 01:50:34.000
kann ich sehr empfehlen.

01:50:35.000 --> 01:50:37.000
Versuch das so zu erklären, dass du

01:50:37.000 --> 01:50:39.000
die Ergebnisse

01:50:39.000 --> 01:50:41.000
oder die Erkenntnisse

01:50:41.000 --> 01:50:43.000
in Python genauso anwenden kannst.

01:50:44.000 --> 01:50:45.000
Und

01:50:45.000 --> 01:50:47.000
finde ich immer wieder sehr interessant.

01:50:47.000 --> 01:50:49.000
Gehe sehr oft wieder drauf zu.

01:50:50.000 --> 01:50:50.000
Für die

01:50:50.000 --> 01:50:52.000
Programmiersprachen Interessierten.

01:50:53.000 --> 01:50:54.000
Ja, sehr cool.

01:50:54.000 --> 01:50:57.000
Also quasi diese Analogie oder diese Metapher

01:50:57.000 --> 01:50:59.000
habe ich auch schon häufig gehört. Ich wusste aber nicht, wo sie

01:50:59.000 --> 01:51:01.000
herkommt und ja, das muss ich auch irgendwo mal lesen.

01:51:01.000 --> 01:51:02.000
Ne, da gibt es tatsächlich noch was Älteres.

01:51:02.000 --> 01:51:03.000
What Color Are Your Bits?

01:51:04.000 --> 01:51:06.000
Das ist von 2004.

01:51:07.000 --> 01:51:09.000
Da geht es um die Herkunft von

01:51:09.000 --> 01:51:10.000
Bits.

01:51:11.000 --> 01:51:12.000
Also ob deine Bits

01:51:12.000 --> 01:51:14.000
urheberrechtlich geschützt sind oder nicht.

01:51:15.000 --> 01:51:17.000
Was du damit machen kannst,

01:51:17.000 --> 01:51:18.000
um die Farbe, damit sie die Farbe ändern.

01:51:19.000 --> 01:51:20.000
Aber das ist, ja. Also ich

01:51:20.000 --> 01:51:23.000
musste da auch zuerst dran denken. Also es scheint eine gute

01:51:23.000 --> 01:51:25.000
Metapher zu sein. Wir können das ja beides

01:51:25.000 --> 01:51:26.000
verlinken. Ja, sehr gerne.

01:51:27.000 --> 01:51:28.000
Ja,

01:51:28.000 --> 01:51:30.000
ja, cool. Ich würde

01:51:30.000 --> 01:51:32.000
sagen, herzlichen Dank, dass ihr heute alle wieder da

01:51:32.000 --> 01:51:33.000
Aber herzlichen Dank, Stefan.

01:51:33.000 --> 01:51:34.000
Herzlichen Dank, Johannes.

01:51:34.000 --> 01:51:35.000
Ja, danke für die Einladung.

01:51:36.000 --> 01:51:36.000
Freut mich sehr.

01:51:36.000 --> 01:51:37.000
Sehr gerne.

01:51:37.000 --> 01:51:39.000
Dann, ja, bleibt uns gewogen.

01:51:39.000 --> 01:51:40.000
Schaltet uns wieder ein.

01:51:40.000 --> 01:51:41.000
Hört uns, wo immer ihr gerade seid.

01:51:41.000 --> 01:51:42.000
Morgens, mittags, nachts, abends.

01:51:43.000 --> 01:51:45.000
Tagsüber zum Schlafen, zum Einschlafen.

01:51:46.000 --> 01:51:47.000
Einen wunderschönen Tag.

01:51:48.000 --> 01:51:49.000
Bis bald.

01:51:49.000 --> 01:51:50.000
Tschüss.

01:51:50.000 --> 01:51:50.000
Ciao.

01:51:51.000 --> 01:51:51.000
Tschüss.
