Rozbudzono rozum, a gdzie schował się demon z zeszytem? Ten od zeszytu: Maxwell's demon - Wikipedia Znowu jest czas pografomanić na robocie. Oczywiście nie tylko tym się zajmuję. Dopiero co drażniłem się z przedemerytalnym Dżołke (gdyby z odpowiednią fonetyką odczytać lokalnie używane zdrobnienie Jego imienia, to tak by brzmiało), który pieniacko rezonował na temat stosunku do pracy kontrowanego “za tyle to jest tak”. Czyli standardowe bai lang, tang ping. Ale on jest z tej jeszcze boomerskiej epoki, gdzie istniały pojęcia wysługa lat, urlop, a nawet inne błędy i wypaczenia. Wypadałoby zahaczyć o jakiś temat, a dwa rozgrzebane zostawiłem na piecyku w jaskini, więc…
Keycode jest z morsea, i późniejsze kodowanie ascii.
Zgadnij czy w kodzie morsea potrzebowali skrócić polecenia skasuj, wklej, koniec.
Oczywiście ludzie obsługujący sieć telegraficzną na pewno nie maczali łap w jakiś tam przełącznikach do kompiutrów?
O czym jest tekst?
Pamięć jak koń jaka jest każdy widzi… Można tam pisać wszelkie bzdury a jak przyjdzie złośliwy nerd to zacznie bazgrać na tej tablicy zer i jedynek co mu przyjdzie do głowy to się zaczyna zabawa…
z wysokiego poziomu to jedyny “kompilator” który to ogarnia to Rust I to nie dlatego że jest taki sprytny tylko dlatego że jest aż tak upierdliwy dla kodo klepcy…
o “abominations” jak pytong nie będę wspominał bo to jest jak biurwa która zakłada nieskończoność zasobów i wiarę w nieomylności lib’uf których używa jako egzekutoruf na sprzęcie.
…
Dlatego złośliwe nerdy i inne służby które chcą coś się dowiedzieć operują na głównie na level memory od 2dekad bo większość małp klepiacych kod wliczając mecha-malpy w postaci LLMuf dawno zapomniała że to się gdzieś musi wykonać…
Obecnie na samym jądrze cpu są już bezpieczniki. Oczywiście możesz odpalić z własnego biosa i zrobić co uważasz, ale jak Ci się chce dłubać we wszystkich instrukcja obecnych core, żeby cokolwiek na tym odpalić… To się odrobinę złożone zrobiło… może dlatego jest odrobinę dziurawe?^^
A niedziurawe i odrobinę dziurawe to są zupełnie różne wartości.
Powiedzmy, że niszowy dla emerytów. Mi nie przeszkadza, ale nie odczuwam potrzeby.
Słusznie. Herezja, którą trzeba ogniem i żelazem!
Tak, ale jest tam też dość sporo zabezpieczeń “mechanicznych” w kolejkowaniu.
Trzeba dużo w samej obsłudze core wyłączyć, żeby puściło pewne dziwactwa.
Nie zgodzę się. Python to takie samo osiągnięcie jak kątówka/flexa.
Są lepsze, są i gorsze rozwiązania. Zależy kto co i do czego potrzebuje.
Np. taki Lisp został wymyślony, żeby nie rozróżnić co się pisało po pijaku, a co na trzeźwo. Za każdym razem jest tak samo nieczytelne
Nie jest. Morsea code ma zmienną długość znaków, teleksy i ASCII nie. Tzn oczywiście że ludzie co projektowali alfabet dla teleksów pracowali wcześniej z kodem Morsea, ale jest tam przejście fazowe. Między teleksem a ASCII nie ma.
Tak, mam przed sobą pierwsze wydanie (1988/9) "Przewodnik po informatyce" Rolanda Wacławka (Politechinka Gliwicka/Siemanowice Sląskie). I jest tam piękna fraza w roździale o językach programowania: “Który język porgramownania jest najlepszy? Równie dobrze można roważać wyższość skrzypiec nad puzonem. Pewne utwory lepiej zagrać na jedym instrumencie, inne na drugim”
I on ma dużo racji (omawia tam assembler, logo, forth, basic, fortran, C, pascal), choć złośliwie bym skomentował, że choć “fortepian najepszy, to nie ma nic bardziej zmysłowego niż kobieta grająca na wiolonczeli”. No i na wiolonczeli można zagrać to, a na fortepianie się nie da (choć podobno Marta Argerich umiała)
(ja ktoś nie czytał, to może zacząć od tego, bym się nie powtarzał)
Uwaga wstępna
Najważniejsze: trudność w programowaniu nie polega na tym by pisać najbliżej kodu maszynowego. Trudność polega na ubraniu machania rękami, rozmów z biznesem i niesprecyzowany oczekiwań w formalizm. Bo wszystkie języki programowania mają to do siebie, że są językami formalnym, podczas gdy ten od Bladawców jest zupełnie inny. Nasz najbliższy formalizm języka ludzi to jest własnie LLM/AI czyli coś wysoce stochastycznego. Owszem, niektóre algorytmy (np miotła paraboliczna, czy zaawansowana numeryka) mogą być baaardzo skomplikowane, ale to jest kwestia z innego, wyższego, poziomu abstrakcji.
Wszystkie te języki formalne, z gramatykami LL1 i LR1 są dużo bliższe sobie, nawet jak mówimy o assemblerze 6502 vs Agda niż język ludzki jakiemukolwiek językowi programowania.
Bo gramatyki formalne i towarzyszący im determinizm automatów skończonych sprawa, że relatywnie łatwo można tłumaczyć jeden język programowania na drugi. To nawet ma swoją teorię i jest starsze niż jakiekolwiek fizyczne “maszyny liczące”. Matematyka z jej formalizmem była jak zwykle wcześniej niż działające prototypy zastosowań praktycznych. Turing, Ada Byron, rachunek Lambda Church’a.
[edit] Poza algorytmami, optymalizacją i formalizacją problemu to elementem wymagającym wysiłku (trudnym) w programowaniu) jest tez zażądzanie zlożonościa i zależnościami W sensie dużo łatwiej jest w komputerze niż w realu stworzyć system o wykładniczo rosnących stopniach swobody i kwadratowo rosnących zależnościach. W tym sensie języki programowania powinny nie tylko ułatwić nam sformalizowanie problemu/rozwiązania, ale zrobić to tak, by ograniczać niepotrzebną złozoność (wszystko powinno być tak proste jak tylko się da i ani trochę prostsze, polecam ksiazkę Perełki oprogramowania)
uwaga: jak ktoś będzie z tym lematem polemizował na poważnie, to znaczy, że nie wie o czym mówi:)
Polemika z artykułem
Zacznę od tego, gdzie @3r3 ma rację: ma tam gdzie opisuje historię hardware. W skrócie i uproszczeniu tak było.
To w ogóle jest kwestia definicji, bo komputerem nazywamy maszynę którą można zaprogramować do wykonywania sekwencji operacji matematyczno logicznych.Zakładając dla uproszczenia, że pierwszym komputerem był ENIAC (co nie jest prawdą, były wcześniejsze próby zarówno działające, jak Collosus z Bletchley Park jak i niedziałające), bo ENIAC był nie tylko zbudowany realnie, ale też był zaprojektowany jako ogólnego przeznaczenia (Turing w Bletchley miał jedno zadanie: łamanie Enigmy).
W tym konteksie praktycznie od początku nawet jak program wprowadzało się stycznikami był to binarny ciąg znaków z instrukcjami. Assembler binarny. Czyli język formalny, z resztą łebscy ludzie nad tym pracowali (Curry, von Neumann, Turing).
Czyli możemy dla uproszczenia powiedzieć, że programowanie od początku było wyrażaniem w języku formalnym instrukcji dla komputera w jaki sposób i co ma wykonywać.
Assembler
Jeszcze taka uwaga symboliczna. Assembler binarny, czyli numeryczne kody instrukcji, został szybko wzbogacony o odpowiednik symboliczny, tzn każdemu kodowi przypisany jest alfanumeryczny mnemonnik, gdzie tłumaczenie może być czysto mechaniczne - tzn klawisz “JMP” wybija na karcie dziurki w odpowiedniej kolejności. I to jest ten język assemblera który znam i jest 1:1 odpowiednikiem kodu maszynowego.
Polecam poczytać o CoreWars i ichniejszym assemblerze RedCode który ma raptem 8 instrukcji. To jest dobra zabawa zarówno z punktu widzenia napisania maszyny wirtualnej/areny jak i pisania botów do CoreWars.
Dla bardziej zaawansowanych jest assembler 8bitowych mikroprocesorów z której to epoki jest wspomniania instrukcja POKE. Stare dobre czasy atarynek.
Co jest dobre w tekscie
Bardzo mi się podobał wątek o wpływie skandynawskiego modelu edukacji, na autorów wdrożenia programowania obiektowego jako analogii z biologicznymi organizmami. Tego rzeczywiście brakowało w wideo, a w pewnym sensie odkrywa przed nami scieżkę dlaczego i jak te paradygmanty były kształowane
Chyba trudniej:) To znowu jest wszystko na opak. Jeśli wyjmiemy z OOP dziedziczenie i polimorfizm (trochę tak jest w rosnącym w siłę GOLang) to mamy mechanizm łączenia typu z funkcją. Z punktu widzenia programisty wysokopoziomowego wszysto jedno czy jest Moduł X z typem dany Y, Z i funkcją X::f(Y)->Z czy zmienimy sekwencje i mamy X::Y.f() → Z.
To jest 1:1 dokładnie to samo.
To jest trochę chaotycznie napisane ale przynajmniej jest prawdą i to dosyć istotną. Model wdrażania liczb zmiennoprzecinkowych w komputery był bardzo bolesny, trudny (algorytmy stabilnie numeryczne w Fortranie to jest kosmos) i powolny z powodu ograniczeń sprzętowych. Z resztą ze śmiesznych rzeczy, to dziś idziemy w odwrotną stronę, bo LLMy na GPU zaczynaja działać na 2 i 4 bitowych floatach.
Pomieszanie z poplątaniem
Ja wiem, że oryginalny wpis miał charakter uproszczony ale potem następuje absolutne pomiesznie rzeczy ważnych z nieważnymi w jakieś nieliniowej chronologii:
Cały fragment od
do
brzmi jakby ktoś wrzucił książkę w blender i dodał gazu:)
memory isolation
Zacznijmy od tego, że realnie ochrona pamięci jest związana z wieloprocesowością. W komputerach domowych pojawiła się w epoce 80386 (choć w teorii od 286), czyli w latach '90, grubo po tym kiedy programowanie obiektowe w Simuli czy Smalltaku zostało wymyślone.
W mikroprocesorach z serii 8-bitowej czy 8086 (assembler x86, jedyny w którym realnie programowałem), można było sobie pisać gdziekolwiek o ile był to RAM (bo część adresów mapowała był na ROM, gdzie z oczywisych względów nie dało się pisać).
Oczywiście mechanizm zabezpieczenia pamięci jest dużo straszy, bo w uproszczeniu został wprowadzony w mainfraimach na przełomie lat '50 o '60. (S/360 IBM).
Ale - i to pomieszanie mi chodzi - mamy w zasadzie dwa podstawowe i ortogonalne mechanizmy ochrony: na poziomie języka i na poziomie systemu operacyjnego.
Na poziomie systemu operacyjnego to jest właśnie S/360, 386 czy Windows XP (bo żeby było zabawniej, to Windowsy z serii 9x nie używały tej ochorny pamięci w pełni, dlatego do Diablo były fajne mody, co podmieniały pamięć:)). To jest mechanizm gdzie przestrzeń adresowa jest wirtualna, tzn system operacyjny+procesor tłumaczą na adresy fizyczne tak, by sobie programy i użytkownicy nie wchodzili w paradę. I można sobie w assemblerze robić dzikie harce, ale nic to nie zmienia.
Na poziomie języka, chodzi po prostu o to by nie używać assemblera/nagich pointerów i mieć tablice które wywalają się przy wyjściu poza indeks. Pierwszy język programowania wysokiego poziomu Lisp (1958, od razu z garbage collectorem) tak miał. W tym sensie softwareowa/językowa kontrola pamięci jest starsza niż systemowa (bo też jest prostrza choć mniej wydajna). Z innych języków epoki Gomułki, to COBOL i Basic są bezpieczne (i wolne), Fortran nie (ale za to szybki). Generalnie widać, że języki interpretowalne były bezpieczne, kompilowalne nie.
Pierwszym bezpiecznym i szybkim językiem kompilowanym językiem był Algol (1958), potem Simula (1962 z GC!), Pascal (1970).
dynamic allocation
I tu wchodzimy w drugi podtemat: dynamiczna allokacja pamięci. Po pierwsze dynamiczną allokację pamięci można sobie zrobić wszędzie, wystarczy mieć własną byte i tam trzymać co się chce. To z resztą jest znany trick z języków typu Basic czy Fortan, by zrobić LinkedList.
Po drugie, pamięc (nawet dziś) jest przydzielana procesom przez system operacyjny w stronach (które mają izolację fizyczną) i dopiero wewnątrz nich można sobie brykać wskaźnikami. Znowu: w świecie prymitywnego 8068 czy Commodore był ein proces, ein uzytkownik ein pamięć i keine grentzen:) Więc na poziomie OS nie było izolacji, ale można sobie było ją robić na poziomie użytkownia pisząc w językach “bezpiecznych”.
co jest nie tak
Film oryginalnie jest o historii OOP i OOP nie jest ani potrzebne do bezpiecznego zarządzania pamięcią, ani jakoś wybitnie nie poprawia zarządzania dynamiczną pamięcią. Esencją OOP jest dziedziczenie i polimorfozm (funkcje wirtualne) jako mechnizm abstrakcji danych. I o wadach takiego podejścia była oryginalna prezentacja.
W wielkim skrócie główną wadą (poza rakiem mózgu:)) jest to, że w klasycznym OOP masz swoje abstrakcyjne typy danych (ADT) jak lista czy kopiec i wrzucasz tam wszyko luzem (var l = new List(). l.Add(1) l.Add(“2”)) i przez to tracisz na etapie kompilacji informacje co tam siedzi i błędy z tanich (compile time) wchodzą w drogie (runtime).
Dlatego w C++ ostatecznie ADT są zrobione za pomocą templeateów które wykrywają takie problemy na etapie kompilacji.
Można by sobie wyobrazić dodanie templatów do TurboPascala i mieć język bez prawdziwego OOP ale z bardzo potężną, bezpieczną i szybką abstarakcją jak List czy Heap<any_record_type_>.
Wątek poboczny: C++ tak naprawdę nie do końca umie w template’y, bo one muszą być rozwinięte na etapie kompilacji, czyli nie bardzo można je umieścic w sposób abstrakcyjny w plikach .o czy .dll. Dlatego własnie cały STL jest w .h i musi się za każdym razem kompilować na nowo.
Strong data types
Cały ten fragment jest znowu nonsensem. Typy istnieją de facto tylko na etapie kompilacji. Ewentualnie w maszynach wirtualnych języków typu .NET czy Java.
async, pamięć, stos, GC
Brakuje mi jeszcze jednego nomen omen wątku. Pamięc lokalną (dla danej funkcji, procesu, wątku) kontroluje się i zwalnia bardzo prosto: Return & Free. Podobnie bufory sprzętowe (nieizolowane) - ich się nigdy nie zwalnia, bo ekran nie znika.
Problem de facto mamy z pamięcią roboczą która jest używana pomiędzy kolejnymi procesami/wątkami/funkcjami. Najprostszym upierdliwym przykładem jest przekazywanie tekstu/stringów do UI gdzie coś ma być wyświetlone. Można to robić wolno/kosztownie przez wartość (kopiowanie) albo przez referencję i wtedy zaczyna się koszmar kto za to odpowiada.
I w moim oryginalnym tekscie o tym pisałem. Obiekty, Windows, VisualBasic, SmallTalk/objectiveC etc: tam wszędzie za sukcesem stała kwestia używania GC i uproszczenia obsługi pamięci w UI/UX. Nawet nie w samym programie, tylko w kopaniu się z koniem/uzytkownikiem.
GC ma mnóstwo wad i ograniczeń (polecam historię z Jane Street jak naprawiali GC w Ocamlu na wielu wątkach) ale całkiem sporo rzeczy można zrobic bez niego (w sposób relatywnie deterministyczny/tani/szybki): patrz Rust. Albo specyficzny pseudo-GC w 8-bitowych BASICach który operował tylko na stringach (ref counting) bo tam nie ma referencji cyklicznych.
kiepski kod
W assemblerze czy C (to też de facto assembler tylko z czytelniejszą składnią, przecież tam każda funkcja tłumaczy się prosto na kod maszynowy. StrCpy to jest przecież REP MOVSB) też można pisać kiepski kod:) Jaka płaca taka praca i jak sobie pościelesz tak wyśpisz. Płaci się za kod który ma być na wczoraj i działac źle i zatrutnia się kiepskich ludzi, to tak wychodzi.
To jest błędna teza. Przyczyny lagów są trzy. Z jednej strony owszem część bierze się w z tego, że piszemy system czasu rzeczywistego w pythone, ale większość to kwestia synchronizacji wątków w legacy codebase (to jest duuży problem, zobaczcie sobie co robi wasze CPU kiedy komputer laguje: generlanie nic nie robi, czeka). A przede wszystkim z lagami jak z korkami: wypełniają całą przestrzeń do granicy bólu ale nie bardziej, bo potem klienci zaczynają wymagać.
To chyba w jakimś dzikim kraju. Natomiast w poważnej edukacji (jak MIMUW) to od zawsze się stara oddzielać te ortogonalne problemy. Uczy się osobno algorytmów, osobno assemblera/bebechów i osobno “myślenia funkcyjnego” by to potem złożyć w całość i pokazać “jak jest”. To jest bardzo dobre podejście (widać po wynikach), a poza tym pozwala opanować skakanie po poziomach abstrakcji.
premature optimization is the root of evil
Tak. Ale komputery mamy po to by rozwiązywały problemy homosapaczów, a nie problemy rachunków. Rachunki nie mają problemów, żyją sobie w świecie idei platońskich i są czasem podglądane przez matematyków.
Dlatego “upierdliwe” języki programowania, Ocamle, algorytmy etc są dobre, bo pozwalają rozwiązywać problemy wg logiki zachłannej. Tam gdzie są największe uzyski. Jak już mamy dobry formalizm tego co chcemy rozwiązać, dobry algorytm, poprawną implementację to możemy sobie potem robić profiling fragmentów które używają najwięcej zasobów i optymalizować sobie w assemblerze. Choć realnie mam duże wątpliwości, że pomijając jakieś błędy (typu bardzo ważne i wspomniane branchless optimizaion) to czy człowiek a większą skalę jest w stanie wycisnąć coś więcej niż współczesne kompilatory C na baaaardzo trudną architekturę jaką jest CISC/amd64 - nie wiem.
ai
w skrócie moja - skądinąd wyssana z palca teza jest taka, że w epoce LLMów i agentów (czyli LLMy w pętli z kompiliatorem) lepiej używać języków “upierdliwych” (jak Rust czy Haskell) co się czepiają o wszystko, bo pętla zwrotna jest krótsza i LLM łatwiej się może sam korygować.
Mądrzejsi ode mnie ludzie mówią, że LLM pisze lepszy kod w znanych niż ezoterycznych językach, ale myślę, że to da się jakoś wybalansować.
Robiłem kiedyś projekt z ML rozpoznawania kolorów. To jest dużo bardziej skomplikowane (ludzka percepcja koloru) niż mi się wydawało i widac to po wszystkich obrazkach gdzie linie są jednocześnie białe i czarne, zależy z której strony patrzysz. Albo sukienka złota i niebieska
wnioski
W teorii Rust mógłby powstać w 1985 zmiast C++. Kompilatory Rust nie są od C++ wolniejsze nie są jakoś wybitnie bardziej skomplikowane.
Natomiast Rust ma w porównaniu z C++ bardziej bezpieczny (trudniej przez przypadek odstrzelić sobie nogę) system typów i kontroli pamięci, przy tej samej wydajności.
I to jest moja programistyczna idee fix, dla której wkleiłem ten filmik i której echo jest też w moim pierwszym artykule. Ewolucja języków programowania nie jest tylko limitowana przez ograniczenia sprzętowe (co poniekąd postuluje 3r3) ani przez popyt/podaż (że niby potrzeba nam milion programistów JS). Ale przez fakt, że nasze teoretyczne rozumiemie paradygmatów programowania jest równie istotne jak ograniczenia sprzętowe i że dawkinsowska konkurencja tych paradygmatów trwa, że są gorsze i lepsze oraz że wypieranie jednych przez drugich jest procesem długotrwałym
Replika Z3 stoi w muzeum w Monachium.
1941 rok: Konrad von Zuse.
Kto nie był i na własne ślepia nie widział a z dokarmiania mózgów elektronowych żyje ten śmie uzurpować sobie tytuł “informatyka”. Howgh.
Xterm: lata 80te ubiegłego wieku,
vim: początek lat 90tych ubiegłego wieku.
Od tamtych czasów doszła mysz oraz kolorowe a potem płaskie monitory a vim w xtermie nadal wymiata. Napisane raz za to tak że tam nie ma się co zepsuć.
W biurze u mnie zbudowali replikę Bomby Turinga:) Podobny okres dziejowy, podobna technologia.
Ale tak, wspominałem o tym w pierwszym artykule. Umownie mówmy, że ENIAC był pierwszym komputerem, bo był pierwszym komputerem elektronicznym ( a nie elektromechanicznym).
Tylko Emacs:)
No i a propos wypierania i technologicznego locked-in: QWERTY jest niewydajne, bo jest zaprojektowane jako niewydajne (by się maszyny do pisania nie zacinały). Ale z powodów czysto socjologicznych wydaje się, ze nigdy od niego nie odejdziemy. Choć ja osobiście używam Colemak i sobie chwalę
Jest.
Zwróć baczną uwagę, że cały czas poruszamy się w jednej firmie - Bell Lab.
W razie czego przejrzyj sobie standard ascii któryśtam skąd się wzięły printable i pozostałe.
To jest ciągłość technologiczna w ramach jednego garażu.
Tak. A bladawiec nawet nie jest w stanie we własnym sprecyzować co ma na bezmyśli.
Jakąś maszynę, która przetwarza sygnał w sposób deterministyczny.
I przy okazji można to przetwarzanie zdeterminować majstrując w maszynie.
Jeśli jest się wystarczająco zdeterminowanym oczywiście.
Jak i sterowania każdym superkomputerem.
No niby inheritka to komplikuje, ale pamiętaj, że oni wtedy jeszcze nie wdrażali dupereli w rodzaju method.
Tak.
Ale z punktu widzenia kolejności instrukcji po kompilacji ma.
Szczególnie jeśli nie masz “obiektu nadzorcy” pilnującego syncu w cyklach, tylko każdy sobie na wyścigi.
W fortranie to się nawet dwa zera zrobiły, dla pewności, jedno ujemne, a drugie dodatnie^^
A spróbuj to wyjaśnić komuś, kto odbył stosunek z javą
abs(a)<abs(b)
I to jest bardzo słuszna koncepcja, i ja ją popieram, rozumiem, doceniam.
Lubię to!
Wyjaśnij mi czego nie zrozumiałeś.
Ochrona typów jest na poziomie kompilatora. Jak ją wyłączysz to instrukcji wszystko jedno co jest w rejestrze, char sumuje się z real i mnoży przez RGBA bo to tak czy srak jest ciąg bitów. W rejestrach nie ma carry dla tej zbędnej informacji. A to że program zacznie robić bzdury (zdarza mi się, ujemne kolory zawsze sugerują mi, że gdzieś się walnąłem na gpu ponad miarę).
Dalej można, tylko musisz wyłączyć bezpieczniki uruchamiane przez BIOS.
Aaaa… o to Ci chodzi. Tak, ale uznaję to za oczywistą oczywistość, że przydział jest hierarchiczny. Tak jak hierarchicznie wyżej jest bezpiecznik sprzętowy startowany zwyczajowo z BIOS.
Oczywiście nikt nie broni zrobić sobie modyfikacji BIOSu i takiego OS, któremu wszystko wolno. Wtedy spora część nowoczesnego procesora nie ma nic do roboty, bo w ogóle nie jest wywołana. Ale jak nie zrobisz synców na wątki to się dowiesz dlaczego było tego nie ruszać.
Tak.
Nie rozpędzałbym się z tym twierdzeniem o bezpieczeństwie^^
Że wolne się zgadzam.
Tak, ale to wynika z budowy kostki. O czym się łatwo przekonać, kiedy rozmiar structu z danymi (a nie referencjami do innych) wyjdzie za ramkę kostki. Formalnie to błędu nie zwraca, że wyszedł, po prostu tego nie ma.
Była, zakres adresowania wynosił 64 i tyle miała kostka. W kolejnych wersjach 128 i amisi nihil novi.
Jeden widzi film o piratach, drugi romans, trzeci sceny batalistyczne
Czyli ten film to kino familijne
Czyli podstawowe DSy.
W zasadzie to tak używam czegokolwiek. Czy to jest obiektowe średnio mnie, ważne żeby nie pytało o typy danych, sam sobie upilnuję.
Chodzi Ci o to, że nie są oflagowane.
Odnosiłem się do tego, że wysyłanie na urządzenie, które nie czyta danej instrukcji jest typem danych. Dlatego drukajka jest podana jako źródło.
Ale to nie przesuwa układu i masz fragmentację.
Jest nadpisywany w cyklach. Jak postawiasz cykle z d to zdążysz zobaczyć no signal. Zdarza się jeśli monitory mają różną częstotliwość wyświetlania, a apka przewiduje tylko jedno ustawienie.
A jeszcze dokąd trafia return na zamknięcie funkcji^^
Dobro doszli - w tekście dużo o tym napisałem, że tu chodzi o użyszkodnika i jego niefrasobliwość graniczącą z kalectwem.
Można, ale nie wypada.
Ale piękna.
Czeka bo ma instrukcje dla core0, a pozostałe agresywnie czekają na rozkazy.
To chyba stary jestem, bo uczyłem się od ludzi, którym jeszcze nie było czego rozdzielać, a właśnie z tego ośrodka detencji, bo tam mieli kompiutry.
Sugerujesz, że nazwa komputer nie ma związku z computing?
Ale wtedy nie mają ograniczonej bitowo dokładności. Są piękne w swym continuum. Te które podglądamy są na miarę kanciastych brył, starających się ukryć niedoskonałości przed słabym wzrokiem w double precision.
Znamy odpowiedź. Nie jest.
W każdym razie nic istotnie złożonego.
Tak, Ala. Ala jest taka, że kiedy chcesz puknąć coś na wyświetlacz bardziej złożonego od znaczków to musisz się pomiziać z gpu. No i przyjmując, że nie jesteś zboczeńcem, a odpalisz opengl tam jedyny błąd jaki zwraca kompilator, to numer linijki, która mu nie podeszła. Bez informacji dlaczego, o co chodzi, czy na pewno o tą linijkę, czy eol brakło dwa akapity wcześniej.
Prosty owszem. Ale nie umie się zagnieżdżać.
Znaczy do napisania aplikacji musisz go dozorować.
Do tego ma straszne ilości śmieci w danych treningowych. Na przykład wymyśliłem lepszy kod sprawdzania kolizji niż się naumiał i każdy llm szedł mi w zaparte, że tak mam być, kiedy ms wykonania sprawiały sprawę jasno - moje lepsze.
Tak, do tego potrzeba kobiet. Dla mnie morze, niebo, kubek, koszulka - wszystko niebieskie. A te mają na to jakieś określenia.
Łososiowa, miętowa… nie mój poziom abstrakcji.
RGB.
I za to z Tobą wypiję.
Towotem!
Powiedzmy, że to była elektronika. No tak średnio, ale niech będzie.
Mi nie przeszkadza.
Znaczy sterowanie w grze zamiast W ASD masz W ARS?
W ASD jakoś znoszę, w ARS to już inne upodobania.
to weź się proszę zdecyduj czy komputer jest programowalną maszyną liczącą czy też komputer jest elektroniczną a programowalną maszyną liczącą.
Wedle Twej pierwszej a wcześniejszej definicji (do niej się odnosiłem) pierwszym komputerem był Z1 (ale się zawieszał) lub Z3 (bo się nie zawieszał). Wedle Twojej drugiej definicji to Amierikańce mają dłuższego.
Zwracam uwagę że maszyny wymyślamy do rozwiązywania problemów i zwisa nam zwiędłym kalafiorem jak one te problemy rozwiązują (tutaj: przekaźnikami czy lampami), tak długo jak maszyna rozwiązuje postawiony jej problem szybciej i taniej niż analogowy bioprocesor z jednym core oparty o całe dwie nóżki.
Dlatego stawiam w wątpliwość czy Z1 był pierwszym komputerem. Bo się zacinał. Co do Z3 tej wątpliwości nie mam. Maszyna, programowalna, licząca. Działała dopóki jej nie konkurencja nie zbombardowała.
Jest to podział arbitralny, w podręcznikach jest ten drugi, ale ja się zgadzam na oba; o czym wspomniałem w artykule na tym portalu już w 2021:)
Colemak był projektowany by zminimalizowac liczbe zmian względem QWERTY i w miarę zredukować obciążenie przy pisaniu. Mi pomógł na zespół cieśni nadgarstka, dlatego polecam:) Udało mi síę przesiąść z QWERTY po trzydziestce w weekend:)
Problem rozwiązany po kilkukroć przez Unreal, DirectX, SDL czy OpenGL. W sensie: masz rację, ale robienie takich rzeczy ręcznie dziś, to jest hobby jak auta na żółtych blachach czy moje programowanie w GW-BASICu. Plus Rust czy Zig tak samo jak C mogą pisać po pamięci GPU.
Nazwa wskazuje, że komputery liczą. Czyli rozwiązują problemy ludzi z rachunkami. Są też takie miejsca, gdzie w czasach Konrada Zuse rozwiązywano problemy rachunków z ludźmi, ale to były inne miejsca:)
Algorytmika jest istotnie starsza niż komputery. Pamiętaj w jakim mieście stacjonuję:) i tu mamy kilka ulic upamiętnianych twórców algorytmów zanim powstały komputery. Relacja programowanie-komputery to trochę jak matematyka-fizyka. Kochajmy się, ale z ostrożna.
:))))
Dużo lokalnych rzeczy jest allokowane na stosie, wtedy problem z fragmentacją nie istnieje. Ale masz rację w ogólnym przypadku. Stąd wprowadza się niezależne sterty(heap) by móc nad tym panować. Trik stary jak świat, gość który mi to pokazał dwie dekady temu już wtedy był w wieku przeemerytalnym.
W ogóle właśnie Zigjest językiem z obsesją nt kontroli procesu allokacji pamięci. On by ci @3r3 w sumie pasował. To jest takie napisane na nowo C, z enkapsulacją, ale bez obiektów. Z ręcznym zarządzaniem pamięcią (bardziej jak C niż Rust).
To jak diesel i bezynowy silnik czterosuwowy. Niby podobne, ale jest tam technologiczne przejście fazowe.
Odróżniamy liczydła/kalkulatory od komputerów dlatego. Elektromechaniczne kalkulatory sumacyjne dla księgowych są dużo starsze niż komputery.
Wyjasniłem. Problem nie polega na tym ze zmyśliłeś fakty, tylko że wszystko jest przemieszane. Rozmawialiśmy o tym na spoktaniu, że teksty są za duże i zbyt hermetyczn złośliwy mode on
“Język giętki powiedział wszystko co pomyśli głowa”. Pisanie dla ludzików ma trochę współnego z programowaniem. Jak to mówił Dukaj, musisz w kulturze pisma przerobić swój memory dump na format liniowy. A Ty tradycyjnie zrobiłeś printscreena i “pora na CS’a”. Ten aspekt jest podobny do zarządzania złożonością w systemach informatycznych.
Na tej konferencji Better Software był tez wykład o tym, że każdy program powinno się dać napisać przez jedną osobą (to prawda). Ale nie każdy problem da sie opisać tak by zmieścić go w całości na raz w głowie:) złośliwy mode off
Tak tak, sam to napisałem z pogrubieniami. W sensie ja się generalnie zgadzam, tyle że oryginalne wyjaśnienie było źle napisane (choć poprawne).
Czy kopiec Fibbonaciego jest jeszcze podstawowy czy już zaawansowany? Ale tak to jest ważny wątek: jak zaimplementować podstawowe struktury danych i algorytmy (np sortowanie) tak by można było je używać na róznych typach danych. W takim TurboPascalu jest to baaaardzo trudne: nie ma polimofizmu, templateów, makr ani uniwersalnych wskaźników. Owszem można próbować to obejść za pomocą strongly-typed function pointers i wrapperów (getterów/setterów) na wszystko ale jest to MEGA upierdliwe. Prościej zrobić copy&paste. W sensie wbudowany w język mechanizm który umożliwia taką abstrakcję ułatwia życie, a w runtime nie kosztuje nic (jak templete/STL)
złośliwy mode on
Ustalmy raz na zawsze, bo już w 2021 o tym rozmawialiśmy. Ty nie rozumiesz co to jest OOP. I nie ma w tym nic złego, jak pokazywał tamten wykład od którego zaczeliśmy mało kto rozumie co to jest OOP i po co, nawet twórcy mieli z tym problem.
Poza tym, to nie czyni z Ciebie złego programistę:) W sensie masz na tyle doświadczenia, że widzisz, że OOP jest bez sensu (bo w większości wypadków jest, znowu o tym był tamten wykład). Ja tez nie lubię OOP, zawsze wydawało mi się nieproporcjonalnie komplikujące życie w stosunku do wartości dodanej (w odróżnieniu np od templateów).
Po pierwsze, najbardziej wplywowy język obiektowy (C++) w ogóle nie miał takij izolacji danych co do obiektu/nadzorcy. Tam sobie można było brać function pointer do metody i wykonywać ją na zupełnie innych danych.
Po drugie to o czym mówisz, to sie nazywa enkapsulacja i można to robić bez obiektów. Wystarczy struct i namespace. Nawet w TurboPascalu od biedy sie da (record + unit). Pomijając już, że puryści obiektowi to w nic bardziej pokręconego niz objectiveC i ruby nie schodzą. Bo C++ ze swoimi klasami próbował dosyć nieudolnie pożenić język niskopoziomowy (C) i z bardzo wysokopoziomowym (Smalltalk/simula) i mamy z tego prawdziwy paprykarz szczeciński (który wbrew nazwie składa się głównie z ryb i ryżu).
[1] Obiekty to hierarchia klas (czyli dziedziczenie/zawieranie się struktur danych w odróżeniu od kompozycji/składania). W C++ w ramach robienia sobie pod górkę mamy chyba trzy rózne rodzaje dziedziczenia i do tego wielodziedziczenie. Idealne źródło pytań na interview. No i nie wolno takich rzeczy używać w kodzie produkcyjnym, tak samo jak nie można robic swap za pomocą xor Żaden inny język nie ma takiego rozwiązania, bo ono po prostu jest głupie. Tylko Python ma wielodziedziczenie (poza C++ z mainstreamowych języków) ale nie ma tam ochrony dziedziczenia jak w C++. No i w Pythonie w ogóle nie ma private/public bo klasa do jest de facto dictionary (jak wszystko w tym wolnym języku).
[2] Obiekty to także polimorfizm/funkcje wirtualne czyli late-binding. Czyli składnia umożliwiająca wybór podprocedury dynamicznie w runtime. Można to robić za pomoca function pointers w C (i tak GNOME choć napisany w C to ma cały system paradziedziczenia i obiektów: GObject), można za pomocą interfejsów z obiektami (jak w C#/Java). Można za pomoca interfesów bez obiektów (jak GO).
Stąd OOP to [1]+[2]. Twoja defincja która mówi OOP=enkapsulacja fałszywie rozciąga nazwę OOP na całkiem sporo niewinnych i przydatnych mechanizmów:) Jak ograniczymy OOP do dziedziczenia+polimofirzmu, to dużo łatwiej widać, że ono jest jeszcze mniej przydatne niż początkowo mówiłes.
A jak wspomniałem: enkapsulację można mieć bez obiektów i żyć szczęliwym.
Natomiast - i to jest plus OOP - polimorfizm + dziedziczenie daje możliwość budowy tych klocków struktur danych/algorytmów etc. To będą klocki z łajna, ale będą:). W sensie w TurboPascalu 4.0 się nie da zaimplementować abstrakcyjnego kopca/prioqueue (taki mały challegne), mimo że w TP jest enkapsujacja. W C się da (bo są “gołe” wskaźniki), albo makra. W C++ są templatey.
Ba, jak dodasz preprocesor cpp do Pascala (można bez problemu) to wtedy juz sie da: na etapie kompilacji preprocesor rozwija makro/pseudotemplate i tworzy substytut abstrakcyjnych typów danych.
złośliwy mode off
PS w wideo od którego się zaczeło, to oni jeszcze mówili o OOP jako modelowany za pomocą hierarchii klas bytów rzeczywistych. Co jak nas uczy doświadczenie jest równie konstruktywnym pomysłem jak jedzenie plastikowych owoców z witryn sklepowych:)
odnoszę wrażenie, że pakowanie Rusta do kernela linuxa było przedwczesne - Zig byłby lepszy
z tego co widzialem to na szybkość kompilatora ludzie strasznie narzekają?
ten oficjalny to chyba bardziej traspiler w ogóle niż pełnoprawny kompilator
W C++ linker to jest katastrofa wydajnościowa. Miałem kumpla co optymalizował linker Microsoft C++. Generalnie modułowość C++ jest niedorobiona i przerzuca dużo na linker. Stąd nie jestem pewien czy Rust dla kompilacji+linkera jest dużo wolniejszy od C++. Ale nie będę się kłocił.
Zdecydowanie. Zig język dla @3r3 i @gruby , tzn język dla prawdziwych mężczyzn:) A dla lalusiów w rurkach Python;)
PS Microsoft Research próbował taki proto-Rust by zabezpieczyć się przed buffer overrun. Prototyp działał, ale projekt został zamknięty. Może w Linuxie chodzi im o to samo?
Ta przypadłość nie wynika jednak z samego LLM czy transformersa, a z infrastruktury, logarytmicznie by rosły przestrzenie wektorów następnej opcji. Bo sam wektor 4096 tak ma.
Vade! Vade Satanas!
To się ciągle robi. Bo jest potrzebne.
Fakt, że spora część rozwiązań to kopiuj wklej, ale… sporo jest obejściami ograniczeń cpu, do kalkulacji czy do pewnych rzeczy, do których architektura normalnie nie jest zdolna (tak jak 3d było zabawą na amisi tak obecnie non euclidian ndimension). Choć może to jest nisza dla zjebów z ASD^^
Jakoś to załadować trzeba.
Tyle, że dla kompilatora zasymulowanie GPU aby wyrzucić błędy jest pozbawione sensu, ponieważ albo wywali brak zmiennej (co jest oczywiste) albo zły :data type (vec3 przypisany do vec4 czy float na mat), ale tak poza tym to dowolny kaszan przeleci przez gpu bez macania i zostanie wykonany - zadanie zjebano z sukcesem.
Do zapłacenia za prąd. Zabierają im cały prąd^^
Imperium Bürokratischer Monster
Ale na komputerze nie każdy algorytm się wtedy mieścił, a chodziło o zastosowania.
Urojonym!
Matematykę się wykorzystuje. Tak aby czuła się zastosowana i prostacko zbrukana.
Próbowano wykorzystać również Matematyków, ale nie przyniosło do żadnych zrozumiałych rezultatów^^
Znaczy tak… moje myślenie jest ciągle na podstawie klocka, który mogę sobie sklecić w domu. Znaczy dla mnie pamięć i jej alokacja jest jak najbardziej fizyczna. Dlatego kartka w kratkę. Wiem że można tę kartkę pociąć po kratkach i żonglować przestawieniem indexów, co przy ciągłości zapisu (braku fragmentacji) nijak nie wpływa na d(t) dostępu.
Przy czym mam na uwadze, że na pewnym poziomie złożoności wracamy do starego problemu, który teraz mieszka w cachu i jest ratowany taktowaniem.
Niby jest, ale to ciągle ta sama firma, ci sami ludzie, ta sama technologia. Im też przedemerytalni pokazywali rozwiązania. To taka ciągłość.
Tak, dlatego podrzuciłem tę żabę, bo ciężko jest wyznaczyć limes dla takiego pojęcia. Ono nie jest ścisłe przez definicję tylko przez ekskluzje, a to na wektor abstraktu w LLM nie działa. Dlatego możemy sobie pyskować o czym mówimy, choć wszyscy wiemy, że robimy to wyłącznie dla konwenansu iż wszyscy jesteśmy w błędzie w czym mamy rację.
To miałbym pisać kilka wątków obok siebie jak LLM?
Jedynym problemem jest chyba sformatowanie tekstu.
Tak, wielu wątków na gpu^^
Dlatego trzeba cały tekst załadować, skompilować i w odpowiedniej liczbie wymiarów wyświetlić. Ten tekst jest o tym, że robimy technologiczne loopy. Historia kołem się toczy, rozwiązujemy problem, który ciągle jest taki sam, i ciągle wracamy do tego samego rozwiązania.
Słuszny zarzut. Przyznaję się.
Zależy w czyjej… Ale po kawałku programy pisze się łatwiej, bo można rozgryźć jakiś zagmatwany problem, zapakować w funkcję, return(rozwiązanie) i zwolnić zasoby.
Nie widzę w tym mode nic złośliwego.
Ale doszliśmy co miałem na bezmyśli.
Czyli zgadzamy się co do kwestii, że z punktu widzenia rejestru tam może być cokolwiek bo to tylko ustawienia przełączników. Czy 4,16 czy 64 to jeden pies. A czy autor miał na myśli float, f32RGBA czy coś innego to jest jego problem.
Wcale^^
Memory dump as is. I sobie peekuj po bitach jak lubisz.
No to jest problem. Niby można programowalnie, zgodnie z ideą programowalnej maszyny na kilku poleceniach. Ale… pewne kwestie można rozwiązać sprzętowo i wtedy jest więcej poleceń więc i dłuższy rejestr poleceń.
Tozależyzm straszliwy.
Po czym ktoś i tak dołoży sobie niestandardowy typ danych, bo potrzebował do symulacji coś takiego opisać i takie jest, a na własnym typie siedem plus pięć plus dziewięć plus trzy bity działa dobrze i nie ma co psuć.
Jeśli chodzi o kwestie edukacyjne jestem wielkim zwolenników get/set. Ale… później nie chce mi się tego stosować i od razu w walę ref.
Jestem w stanie sobie wyobrazić zbiór rejestrów, dla których lepiej żeby było.
Bo jak zgaśnie ekran to ciężko wywróżyć gdzie się zje…
Bo dla mnie to jest taka sama młodzieżowa fanaberia jak gra w słoneczko.
Wiem dla kogo ma sens. Rozumiem. Ale przez to zboczył koderski mainstream i mamy specjację - jak ktoś zrobi coś złośliwego to mało kto ogarnia, że do tego doszło, a już jak to w ogóle.
W pewnym zakresie.
Jak wrzucisz na gpu pointer do tekstury (sampler), który na gpu nie jest w rejonie pamięci dla tekstur to każe się odjaniepawlić i przerwie. Potok się sypnie.
Robię. I jsonem do pliku.
.ini files tak działają.
Jest wiele niszowych rozwiązań c++ pochodnych, które cierpią na to samo. Niby byśmy chcieli asm, no ale tworzy to taką barierę wejścia, że może lepiej nie i spada z rowerka “na później”.
Ale jest stosowane w CAD/CAM bo tam było potrzebne, a że w obu dziedzinach są inżynierowie to stamtąd się wzięło w obie strony.
I żebyś wiedział jak ludzi wqu… ogarnięcie tego.
Ale momencik, tak strukturalnie to jest dla kompilatora kopiuj wklej.
Po prostu ma pewne zasady dodatkowe, kto może z tego skorzystać.
Ale tu już jesteśmy na etapie tworzenia języka jakiegoś tam poziomu.
Po instrukcjach działa tak samo, tylko można nabroić.
Ale tych istotnych dla homo sapka, aby ogarniał bajzel jaki naklepał.
Bo problemem w edu jeśli chodzi o kodoklepstwo była właśnie enkapsulacja - zrobiłem funkcję i niech ona sobie działa, niezależnie od tego w jaki inny program ją wkleję, bo inaczej mamy problem rejestrów procesora - ten numerek jest zastrzeżony dla i wykonuje się tylko na (tu labirynt po ścieżkach otwartych prądem).
No to mam problem z głową, ponieważ za każdym razem wychodzę od konstrukcji urządzenia. Po prostu stary jestem.
Znasz ten problem - rozpatruję elektron w pustym wszechświecie, a chemia jest zbyt złożona^^
Bo to tylko liczby.
Ale uważam, że zbyt dużym kosztem. Znaczy za dużo bagażu to zawiera.
Ponieważ na single core nie trzeba.
Ale to chyba była dygresja.
Chodziło o upierdliwość nowych core. W rdzy była już gotowa obsługa.