Devadesátková hra Brány Skeldalu prošla portací a je dostupná na platformě Steam. Vyšel i parádní blog autora o portaci na moderní systémy a platformy včetně Linuxu.
Lidi dělají divné věci. Například spouští Linux v Excelu. Využít je emulátor RISC-V mini-rv32ima sestavený jako knihovna DLL, která je volaná z makra VBA (Visual Basic for Applications).
Revolut nabídne neomezený mobilní tarif za 12,50 eur (312 Kč). Aktuálně startuje ve Velké Británii a Německu.
Společnost Amazon miliardáře Jeffa Bezose vypustila na oběžnou dráhu první várku družic svého projektu Kuiper, který má z vesmíru poskytovat vysokorychlostní internetové připojení po celém světě a snažit se konkurovat nyní dominantnímu Starlinku nejbohatšího muže planety Elona Muska.
Poslední aktualizací začal model GPT-4o uživatelům příliš podlézat. OpenAI jej tak vrátila k předchozí verzi.
Google Chrome 136 byl prohlášen za stabilní. Nejnovější stabilní verze 136.0.7103.59 přináší řadu novinek z hlediska uživatelů i vývojářů. Podrobný přehled v poznámkách k vydání. Opraveno bylo 8 bezpečnostních chyb. Vylepšeny byly také nástroje pro vývojáře.
Homebrew (Wikipedie), správce balíčků pro macOS a od verze 2.0.0 také pro Linux, byl vydán ve verzi 4.5.0. Na stránce Homebrew Formulae lze procházet seznamem balíčků. K dispozici jsou také různé statistiky.
Byl vydán Mozilla Firefox 138.0. Přehled novinek v poznámkách k vydání a poznámkách k vydání pro vývojáře. Řešeny jsou rovněž bezpečnostní chyby. Nový Firefox 138 je již k dispozici také na Flathubu a Snapcraftu.
Šestnáctý ročník ne-konference jOpenSpace se koná 3. – 5. října 2025 v Hotelu Antoň v Telči. Pro účast je potřeba vyplnit registrační formulář. Ne-konference neznamená, že se organizátorům nechce připravovat program, ale naopak dává prostor všem pozvaným, aby si program sami složili z toho nejzajímavějšího, čím se v poslední době zabývají nebo co je oslovilo. Obsah, který vytvářejí všichni účastníci, se skládá z desetiminutových
… více »V červnu bylo oznámeno, že Apple uvolní programovací jazyk Swift (Wikipedia) jako open source (zprávička). Stalo se tak dnes. Pro komunitu byly vytvořeny stránky Swift.org. Zdrojový kód je k dispozici na GitHubu. Podporován je také Linux.
Tiskni
Sdílej:
Z hlediska návrhu (syntax, konstrukce, styl kódu) jde o jazyk nadprůměrnýPřijde mi jako osekaný C# (což není úplně špatně) s protokoly a vestavěným optional. C# má však lepší GC (Swift používá počítání referencí, což je problematické – cykly + špatný výkon v paralelním prostředí), lepší knihovny a momentálně i otevřenější vývoj.
některé konstrukce v jiných silně typovaných jazycích nejdou napsatTo platí i naopak.
Počítání referencí je lepší z hlediska výkonu.Pro většinu aplikací to neplatí. U aplikací, které používají málo paměti (max. pár GB) a většina hodnot tam má krátkou životnost (tj. krátce po alokaci již nejsou potřeba), je klasické počítání referencí o dost pomalejší, než generační GC s mark and sweep. Proto např. implementace Javy, C# a řady funkcionálních jazyků nepoužívají klasické počítání referencí. Další problémy s klasickým počítání referencí jsou paměť navíc (cache zaplníte počítadly a klesne výkon programu), problémy se synchronizací v paralelním prostředí (opět může značně snížit výkon), problémy s lavinovitým uvolňováním paměti (dlouhé pauzy programu).
Když se nemění čítač referencí, tak nic rychlejšího existovat nemůže.Problém je i s těmi počítadly, jenž zabírají místo v cache. Navíc, čítač referencí se v praxi mění. I když úplně ignorujete všechny lokální proměnné (nevím, zda tohle dělá clang), tak stejně zaplatíte za ZCT (zero count table) nebo něco podobného – viz třeba Garbage collection internals for Flash Player and Adobe AIR, část Deferred reference counting. V určitých situacích může mít dobrý výkon Ulterior Reference Counting: Fast Garbage Collection without a Long Wait, jenže to už je hodně daleko od klasického počítání referencí a od Swiftu.
ObjC cpe čítač referencí do něj, takže se žádná paměť navícJe to paměť navíc na každou instanci (tracing GC potřebuje pár bitů, u počítání referencí to je pár bajtů).
protože jsou "balancing"To samo o sobě nestačí, pokud by počet referencí mohl klesnout na 0 (pak právě potřebujete ZCT).
benchmarky ukazují, že tento způsob (ARC, neboli automatické RC) je výkonnější než "tracing" GC.Pokud znáte nějaké studie, tak se na ně rád podívám. To, co navrhujete, studovali například Deutsch a Bobrow v roce 1976 a později Cann a Oldehoeft v roce 1988 (Reference count and copy elimination for parallel applicative computing). Jsou to jednoduché techniky, které bohužel nestačí na tracing collector (kdyby stačilo něco tak jednoduchého, všichni by to dnes používali).
Many of the optimizations we describe here require the same runtime support as a tracing collector, undermining a principal advantage of a simple implementation. The reference counting implementations in widely used languages such as PHP and Objective-C are naive. Because they lack these optimizations, they are inefficient. Shahriyar et al.’s collector implements all these optimizations and is our RC baseline.
cykly
weak
vim ~/.emacs
BTW. co říkáte na Scalu?Stále je tam řada drobných problémů – například kolekce (problémy s časovou složitostí některých operací) nebo IDE (nepodporují složitější konstrukce) nebo rychlost kompilátoru. Hodně mi tam také chybí TCO, což je ale spíše problém JVM.
BTW. co říkáte na Scalu?Kdybych byl nucený používat Javu jako platformu, tak bych asi šel do clojure.
Co třeba lispovská makra? Quote, quasiquote, unquote? Rekurzivní algoritmy?Makra dnes máte i v jiných jazycích a řekl bych, že i pokročilejší. Například Scala má implicitní makra – nemusí je volat programátor ručně, ale volá je kompilátor automaticky, když potřebuje vygenerovat nějaký kód, jenž mu programátor nedodal (například kód pro serializaci typu – když ho nenapíšete vy ručně, může kompilátor automaticky vygenerovat nějaký default).
meta-circular evaluatorAFAIK tohle už tak rozšířené není a v mainstreamových jazycích ani tak jednoduché (bez dalších knihoven).
Makra dnes máte i v jiných jazycích a řekl bych, že i pokročilejší.Nevím jak ve Scale, ale zatím jsem nikde jinde neviděl nic, co by se alespoň blížilo komfortu procházení po AST stromu. Možná kromě Selfu, kde je možné procházet strom objektů hodně podobným způsobem.
Nevím jak ve Scale, ale zatím jsem nikde jinde neviděl nic, co by se alespoň blížilo komfortu procházení po AST stromu.Ve Scale můžete použít pattern matching anebo
Traverser
.
Tak ano, to jde skoro všude, ale je to stejně komfortní jako v lispu?Na druhé straně ne všechny lispy mají pattern matching – některé transformace AST tam budou asi méně přehledné.
Makra Lispu dokazi diky tomu zmenit syntaxi Lispu a tudiz ho pomoci maker lze doslova transformovat na jiny jazyk.Na to ale potřebujete tzv. reader makra, ne?
Predrecenik asi myslel to, ze diky homoikonicite a makrum neni tezke do jazyka doplnit libovolny konstrukt, ktery potrebujes.Ano, takhle se i Lisp vyvijel. Plno "standardnich funkci" je fakticky makro, ktere muze byt v programu dynamicky rekompilovano a definovat vlastni syntaxi.
Da se totiz pracovat tak, ze si nejdriv napises "rozsireni jazyka" pro konkretni reseny problem (domenu) a pomoci nich resis skutecny problem.Ta rozsireni jazyka mohou byt i velmi drasticka, kdy se fakticky jedna o jiny jazyk. Neznam jiny rozsireny a standardizovany jazyk, ktery by toto umoznoval.
Neznam jiny rozsireny a standardizovany jazyk, ktery by toto umoznoval.Rebol. Ten tedy není zrovna moc rozšířený, ale standardizovaný ano. V srdci je to v podstatě lisp, s trochu jinou syntaxí.
Ta rozsireni jazyka mohou byt i velmi drasticka, kdy se fakticky jedna o jiny jazyk. Neznam jiny rozsireny a standardizovany jazyk, ktery by toto umoznoval.Jde to i v Prologu.
solve(true). solve((A,B)):- solve(A),solve(B). solve(A):- clause(A,B),solve(B).Zdroj: Guide to Prolog Programming, Meta-Interpreters.
Jinymi slovy, jazyk ti dava moznost velice rychle, jednoduse a primocare zavest vlastni DSL a pracovat tak s danym problemem primo, misto toho, abys resil dany problem v jazyce, ktery pro to neni primo staveny a nuti te tak resit spoustu veci okolo.Zavádět si DSL per-problém má imho marginální výhody, general purpose jazyky jsou většinou dostatečně dobré na to, aby se v nich naprostá většina věcí dala rozumně vyjádřit. Naproti tomu to ale má značné nevýhody - je nutné se pokaždé, když člověk přijde k novému týmu / projektu učit nové DSL. Čili tuhle vlastnost bych zhodnotil celkem jednoznačně jako nevýhodu.
Zavádět si DSL per-problém má imho marginální výhody, general purpose jazykyTy ale nevytvaris ciste DSL, ale rozsirujes obecny jazyk o DSL, takze mas obecny jazyk + DSL.
general purpose jazyky jsou většinou dostatečně dobré na to, aby se v nich naprostá většina věcí dala rozumně vyjádřit.To same jde rict i o strojovem kodu, assembleru, ...
Naproti tomu to ale má značné nevýhody - je nutné se pokaždé, když člověk přijde k novému týmu / projektu učit nové DSLToto je naprosto nevalidni argument. V beznych jazycich se musis ucit zase funkce, procedury, metody, ne? Tady navic pracujes jen s dalsi formou abstrakce.blockquote
To same jde rict i o strojovem kodu, assembleru, ...Imho nejde.
Toto je naprosto nevalidni argument. V beznych jazycich se musis ucit zase funkce, procedury, metody, ne? Tady navic pracujes jen s dalsi formou abstrakce.No jo, ale to stále přidělává práci, ne? I v jazycích, které mají makra (třeba makra v Rustu nebo Scale taky pracují s ASTem) je typicky snaha použití maker minimalizovat, používat je pouze pro specielní případy, právě protože zvyšují náklady na porozumění zdrojáku...
Imho nejde.Imho jde. Je to jen o uhlu pohledu na to jakou uroven abstrakce povazujes za dostatecnou, protoze makra nedelaji nic jineho nez pridavaji dalsi formu abstrakce. Jinak pokud jsou bezne jazyky na vsechno dostacujici, proc se na parsovani pouzivaji generatory prekladacu a ne bezne objekty/metodu/funkce? Proc bylo nutne ohnout C#, aby se tam vesel LINQ? Proc v Jave jak na bezicim pasu vznikaji nastroje, ktere pomoci anotaci transformuji jeden kod na jiny? Proc vznikaji ruzne templatovaci enginy, neslo by to delat primo v tom samem jazyce?
No jo, ale to stále přidělává práci, ne?Na to jsi prisel jak? Z pohledu citelnosti je pro me uplne jedno jestli je
(and foo bar)
uzivatelem definovane makro, ci primitivum jazyka.
v jazycích, které mají makra (třeba makra v Rustu nebo Scale taky pracují s ASTem) je typicky snaha použití maker minimalizovat, používat je pouze pro specielní případy, právě protože zvyšují náklady na porozumění zdrojáku...Divas se na Lisp prizmatem druhych jazyku, takze ti vyjde pokriveny vysledek. Tim, ze vsechno je S-vyraz a pouziva se prefixova notace, se ty rozdily hezky stiraji.
Jinak pokud jsou bezne jazyky na vsechno dostacujici, proc se na parsovani pouzivaji generatory prekladacu a ne bezne objekty/metodu/funkce?Nenapsal jsem, že "běžné jazyky" (běžný prací prášek?
Na to jsi prisel jak? Z pohledu citelnosti je pro me uplne jedno jestli je (and foo bar)
uzivatelem definovane makro, ci primitivum jazyka.
Pokud to je uživatelem definované makro, můžu mít pochybnosti, co to dělá. (A to není jen věc Lispu, stejným způsobem je dobré nepřehánět třeba operator overloading v C++ (viz co navařili v U++)).
Jinak (and foo bar)
je velmi jednoduchý příklad, já měl na mysli spíš třeba něco jako (defclass foobar ...)
. Pokud budu vědět, že se pohybuju v CL, budu předpokládat, že se jedná o CLOS (což ale taky nemusí být pravda, že). Pokud budu třeba v Scheme, už moc nevím, co to vlastně dělá, dokud si nepřečtu dokumentaci nebo nerozluštím místní zdroják defclass
.
Pokud to je uživatelem definované makro, můžu mít pochybnosti, co to dělá. (A to není jen věc Lispu, stejným způsobem je dobré nepřehánět třeba operator overloading v C++ (viz co navařili v U++)).To nějak nechápu. Proč bys ty pochybnosti neměl u funkcí a měl je zrovna u maker?
sin(x)
, ktera mi bude pro x vracet sinus, ale pokud budu mit aplikaci pro biblicky krouzek, tak to mi muze vracet seznam hrichu. V cem je problem?
Muzu mit v programu funkci sin(x)
, ktera mi bude pro x vracet sinus, ale pokud budu mit aplikaci pro biblicky krouzek, tak to mi muze vracet seznam hrichu. V cem je problem?
V čem vidím problém jsem popsal na konci příspěvku.
I v jazycích, které mají makra (třeba makra v Rustu nebo Scale taky pracují s ASTem) je typicky snaha použití maker minimalizovatU Lispu jsou makra soucasti jazyka.
, používat je pouze pro specielní případy, právě protože zvyšují náklady na porozumění zdrojáku...Muze a nemusi, skutecne zavisi na tom jak je pouzijete.
U Lispu jsou makra soucasti jazyka.Ve Scale jsou také součástí jazyka.
In Lisp, source filters never break. Never. In Lisp, the **assignment operator** is a macro, implemented by a source filter. Every time you perform an assignment, you are invoking a macro that analyzes the source code at compile time and rewrites it to something else. If source filters were even 0.01% unreliable in Lisp, one assignment in 10,000 would compile wrong, and none of your programs would ever work properly. But they do work properly. That is how reliable source filters are in Lisp. How does Lisp attain this reliability? In most programming languages, syntax is complex. Macros have to take apart program syntax, analyze it, and reassemble it. They do not have access to the program's parser, so they have to depend on heuristics and best-guesses. Sometimes their cut-rate analysis is wrong, and then they break. But Lisp is different. Lisp macros *do* have access to the parser, and it is a really simple parser. A Lisp macro is not handed a string, but a preparsed piece of source code in the form of a list, because the source of a Lisp program is not a string; it is a list. And Lisp programs are really good at taking apart lists and putting them back together. They do this reliably, every day. Here is an extended example. Lisp has a macro, called "setf", that performs assignment. The simplest form of setf is (setf x whatever) which sets the value of the symbol "x" to the value of the expression "whatever". Lisp also has lists; you can use the "car" and "cdr" functions to get the first element of a list or the rest of the list, respectively. Now what if you want to replace the first element of a list with a new value? There is a standard function for doing that, and incredibly, its name is even worse than "car". It is "rplaca". But you do not have to remember "rplaca", because you can write (setf (car somelist) whatever) to set the car of somelist. What is really happening here is that "setf" is a macro. At compile time, it examines its arguments, and it sees that the first one has the form (car SOMETHING). It says to itself "Oh, the programmer is trying to set the car of somthing. The function to use for that is 'rplaca'." And it quietly rewrites the code in place to: (rplaca somelist whatever) There is also a function "nth" that gets the n'th element of a list; if you want to modify the 3rd element of some list, you can use: (setf (nth 2 somelist) whatever) The setf macro sees this and says to itself, "Oh, you are trying to set the third element of something. I know how to do that. I will use the special nonstandard builtin function 'setnth'" And it quietly rewrites your "setf" form to: (setnth 2 somelist whatever) A different Lisp system might rewrite it differently.
zakladni veci jako assignment jsou implementovany jako makroTohle můžete udělat i preprocesory v OCamlu nebo makry ve Scale. Koneckonců plnohodnotný jazyk lze vybudovat i nad lambda kalkulem (tj. stačí proměnné, volání funkc = aplikace funkcí, a definice anonymních funkcí = lambda abstrakce).
preprocesory v OCamluA proto tu mame camlp4, camlp5 ci MetaOCaml, ktere stale vypadaji spise jako experimentalni pokusy. Je komicke, ze padesat let stara Lisp implementace makro subsystemu, ktera se vejde do 40 radku Lispu, se bere jako reference a stale to neni ono (Yaron Minsky, camlp5).
plnohodnotný jazyk lze vybudovat i nad lambda kalkulemTohle je puvodni publikace, kde John McCarthy v roce 1960 predstavil Lisp, a typed lamda calculus mel vliv na jeho design.
Toto je naprosto nevalidni argument. V beznych jazycich se musis ucit zase funkce, procedury, metody, ne? Tady navic pracujes jen s dalsi formou abstrakceS makry lze provádět dost věcí, což je právě ta jejich nevýhoda. Často (alespoň ve Scale) stačí pár maker, která pokryjí většinu potřeb uživatelů (například knihovna shapeless ve Scale). Je pak otázkou, zda jazyk vůbec má mít makra, nebo by bylo lepší přidat funkcionalitu těch pár maker přímo do jazyka.
Makra Lispu dokazi diky tomu zmenit syntaxi Lispu a tudiz ho pomoci maker lze doslova transformovat na jiny jazyk.Na to ale homoikonicita není nutná, ne? Například v OCamlu šlo pomocí nástroje Camlp4 libovolně měnit gramatiku jazyka. Nebo na první pohled "změny syntaxe" můžete dosáhnout v jazycích s mixfixovými operátory. Například if-then-else se tam zadeklaruje jako obyčejná funkce:
if_then_else_ : {A : Set} → Bool → A → A → A if true then x else y = x if false then x else y = y
Koukaje na Camlp4, prijde mi to stale spise jako preprocesor.Ano, je to preprocesor, který v sobě obsahuje gramatiku (skoro) OCamlu. Dříve byl oficiální součástí systému OCaml, nedávno byl však nahrazen PPX. PPX už nedovoluje měnit gramatiku (IDE s tím měla problémy) – místo toho byl AST rozšířen o atributy a PPX může tyto atributy využívat.
Makra Lispu dokazi diky tomu zmenit syntaxi Lispu a tudiz ho pomoci maker lze doslova transformovat na jiny jazyk.Ok. Otázka pro lispisty. Transformujme Lisp na Rust. Mějme následující kód:
use std::thread;
fn main() {
let mut x = Box::new(3); // Alokace resource x. V tomto případě prosté číslo, může to být cokoli...
let t = thread::spawn(move || {
*x += 1; // Mutabilní přístup k resource x
println!("spawned thread: {}", x);
});
println!("main thread: {}", x);
t.join();
}
Kompilace selže na té řádce s tím druhým println
s chybou use of moved value: `x`
, protože x bylo přesunuto do jiného vlákna a je potřeba zabránit race condition (a vyřešit memory management, ale to je v tomto případě vedlejší, protože to v lispu řeší gc). Jak by se tohle udělalo v Lispu?
Mně zajímá, k čemu je ten nástroj dobrý.Prijde mi ponekud nemistne ptat se k cemu je dobry programovaci jazyk. Jinak meta-interpreter je dobry na to, abys pochopil, jak ten jazyk funguje a jake ma vlasnosti, napr. uzavery a lexikalni rozsah platnosti se na tom vysvetluji moc dobre. A to vse na par radcich. Receno slovy klasika: Nechci se vas dotknout, ale ktery programovaci jazyk to ma?
Prijde mi ponekud nemistne ptat se k cemu je dobry programovaci jazyk.Já se neptal k čemu je dobrý programovací jazyk, ale k čemu je dobrý tento programovací jazyk. Kdyby po mě někdo chtěl něco takového například v C++, tak bych se snažil najít třeba příklad nějaké vysokoúrovňové konstrukce, která kompiluje do rychlého kódu (což je imho silná stránka C++), v Rustu by to byl příklad ukazující borrow-checker nebo traits. V Pythonu jednoduchost syntaxe, dejme tomu. A podobně.
Receno slovy klasika: Nechci se vas dotknout, ale ktery programovaci jazyk to ma?Ok, to je obviuhodné, že to Lisp, teď jen ještě kdybych teda věděl, k čemu to je dobré
Já se neptal k čemu je dobrý programovací jazyk, ale k čemu je dobrý tento programovací jazyk.K programovani. To je, jak ptat se k cemu je dobra Java nebo C#.
v Rustu by to byl příklad ukazující borrow-checker nebo traits.To ale neni ukazka k cemu je ten jazyk dobry, ale co uvnitr pouziva.
V Pythonu jednoduchost syntaxe, dejme tomu. A podobně.To opet neni odpoved na otazku, k cemu je ten jazyk dobry, ale jakou ma vlastnost.
Ok, to je obviuhodné, že to Lisp, teď jen ještě kdybych teda věděl, k čemu to je dobréK cemukoliv, k cemu to programator potrebuje. Ja s nim treba chroustam data, protoze program i data splyvaji do jednoho, nemusim resit nejake nacitani XML, atp, proste vezmu data a nactu je do programu jako lispovy seznam) a experimentuju s DSL. Jini s nim delaji symbolicke vypocty. Jini vyuzivaji splyvani dat/programu k tvorbe expertnich systemu a veci z AI. Jini v tom delaji webovky (svuj web mam treba napsany ve Schemu, templatovaci engine je ve skutecnosti jednoducha sada funkci).
Já mam pocit, že třeba uzávěry a lexikální rozsah celkem chápu z ostatních jazyků.Good for you. Ja jsem psal, o tom, ze se tak da jednoduse a rychle vysvetlit cely jazyk vcetne techto detailu.
Ja s nim treba chroustam data, protoze program i data splyvaji do jednoho, nemusim resit nejake nacitani XML, atp, proste vezmu data a nactu je do programu jako lispovy seznam) a experimentuju s DSL.No vida, to už zní jako celkem pěkný praktický úkol...
K cemukoliv, k cemu to programator potrebuje. Ja s nim treba chroustam data, protoze program i data splyvaji do jednoho, nemusim resit nejake nacitani XML, atp, proste vezmu data a nactu je do programu jako lispovy seznam) a experimentuju s DSL.Casto vidam obdobny pristup u ruznych vyvojaru a pokazde si kladu otazku jak se v takovych pripadech resi error-handling ci ruzne chyby kvuli necistote prostredi (timeout TCP spojeni, chyba pri cteni z disku, chybna syntaxe, chyba v kontrole vuce DTD, a mnoho dalsich). Nechme stranou takove to domaci programatorske pohravani si na vlastnim pisecku a mrkneme treba do nenavideneho sveta stredne velkych a obrovskych systemu (napr. "enterprise") plnych XML ruzne kvality a ruznych chyb. Mohl byste prosim v kratkosti popsat vyhody splyvani dat s programem v techto zcela serioznich a v IT zivote naprosto beznych pripadech? Ja za tech nekolik let co si tuto otazku kladu nebyl schopen prijit totiz ani na jednu vyhodu
Tak v prvni rade jde o integritu dat. Separace dat a programu je jedna z cest, jak ji docilit. Lisp tuto separaci umoznuje, homoikonicita tomu nebrani, ta predevsim rika ze data i kod maji stejnou reprezentaci.Pokud jsem Vas spravne pochopil, pak splyvani dat a programu neprinasi zadne vyhody a predrecnik tedy vyuzival tuto moznost pouze na to domaci pohravani si na vlastnim pisecku. Ohledne Restarts atd., po jejich pouziti jiz kod neni vubec pekny a cisty - degraduje to vyzdvihovany Lisp na uroven zcela srovnatelnou s dnesni tvrdou konkurenci.
Pokud jsem Vas spravne pochopil, pak splyvani dat a programu neprinasi zadne vyhody a predrecnik tedy vyuzival tuto moznost pouze na to domaci pohravani si na vlastnim pisecku.Nepochopil a asi ani predrecnika.
K cemu je tedy splyvani dat a programu v neakademickem IT svete dobre,Pak by mozna bylo dobre ujasnit, co myslite pod pojmem 'splyvani'.
kdyz nelze vyuzit dokonce ani na miniaturni zalezitosti typu konfigurace pro JWM (JWM ma kompletni konfiguraci v XML)?Proc by to nemelo byt mozne vyuzit a zrovna s timto programem?
Pak by mozna bylo dobre ujasnit, co myslite pod pojmem 'splyvani'.Myslim to, co deda.jabko popisoval v prispevku vyse, na ktery jsem reagoval: K cemukoliv, k cemu to programator potrebuje. Ja s nim treba chroustam data, protoze program i data splyvaji do jednoho, nemusim resit nejake nacitani XML, atp, proste vezmu data a nactu je do programu jako lispovy seznam) a experimentuju s DSL. Jini s nim delaji symbolicke vypocty. Jini vyuzivaji splyvani dat/programu k tvorbe expertnich systemu a veci z AI. Jini v tom delaji webovky (svuj web mam treba napsany ve Schemu, templatovaci engine je ve skutecnosti jednoducha sada funkci).
Proc by to nemelo byt mozne vyuzit a zrovna s timto programem?Protoze je potreba resit syntakticke vyjimky, chyby pri cteni z disku, chybnou strukturu stromu atd. Tedy pokud vyuziji homoikonicitu, bude kod vypadat prinejmensim tak seredne jako bez pouziti homoikonicity, protoze budu pouzivat Restarts, vyjimky, "signaly" atd.
Protoze je potreba resit syntakticke vyjimky, chyby pri cteni z disku, chybnou strukturu stromu atd. Tedy pokud vyuziji homoikonicitu, bude kod vypadat prinejmensim tak seredne jako bez pouziti homoikonicity, protoze budu pouzivat Restarts, vyjimky, "signaly" atd.Chapete vubec co to homoikonicita je a jake jsou jeji implikace?
Chapete vubec co to homoikonicita jeTezko sebe hodnotit, protoze samozrejme bych rekl, ze ano.
a jake jsou jeji implikace?Zrejme nedostatecne ano, a proto se na ne ptam s ohledem na realne vyuziti a zatim jsem obdrzel pouze stare dobre "jo, zadnou realnou vyhodu to nema" (pouze vyjadreno jinymi slovy). Coz neni nic spatneho. Proste nepekne a ukecane osetrovani chyb je neodmyslitelna vlastnost pri vyuzivani homoikonicity pro externi vstupy, nic vic.
Mechanismus osetrovani chyb v Lispu je ortogonalni a pouzity model je o neco flexibilnejsi nez klasicky try-catch-finally ci event-handler pristup. Serednost je subjektivni zalezitost a objektivni komplexita osetrovani chyb neni vetsi nez v jinych jazycich, osetrovani chyb programu neni vetsinou trivialni.Ano, je flexibilnejsi nez uvedene a komplexita osetrovani je srovnatelna s lehce starsimi jazyky (navrhem). Napr. Google Go je vsak dal (defer) a jazyky s logickym paradigmatem jsou taktez napred. Tedy v takto tvrde konkurenci skutecne pouziti homoikonicity na vstupy silne zaostava.
apr. Google Go je vsak dal (defer)Identicke reseni lze postavit na unwind-protect a lze napsat i makra implementujici chovani defer/panic/restart, i kdyz by to byl spise krok zpet. Lze jit i dale, protoze lispovske Restarts umoznuji osetreni chyby bez odrolovani stacku a ztraty objektu ci dynamicke informace, a lze oddelit logiku ktera rozhoduje jak chybu osetrit a vlastni implementaci osetreni. Osetreni chyb v Go je primitivni a limitujici, ostatne jako temer vse v Go, uz treba jen proto ze v nekterych situacich fakticky nelze psat "exception safe code" a spojuji dohromady exceptions a error codes. Tedy, v cem je konkretne Go s defer dale?
Tedy v takto tvrde konkurenci skutecne pouziti homoikonicity na vstupy silne zaostava.Nechapu co tim chtel basnik rici. Homoikonicita je vlastnost jazyka, ktera nijak neomezuje a jen dava moznosti navic. Znovu, v cem je problem?
Tedy, v cem je konkretne Go s defer dale?V tom, ze prave neumoznuje napr. jednoduse odrolovat zasobnik. Go si vybralo nektere z mnoha abstrakci (ktere lze vytvorit napr. v Lispu pomoci maker) a ty efektivne implementovalo (napr. osekany defer). Je to srovnatelne napr. s ASM versus C, kde C take zahodil mnoho moznosti rucnich hratek v ASM a poskytlo vyssi abstrakci. A v tomto pripade povazuji implikaci jazyk poskytuje vyssi abstrakci by default => jazyk je dale za platnou.
Znovu, v cem je problem?V pouzivani homoikonicity na zpracovani externich vstupu, jakkoliv toto muze zpocatku vypadat nadherne.
A v tomto pripade povazuji implikaci jazyk poskytuje vyssi abstrakci by default => jazyk je dale za platnou.+1, něco takového jsem se snažil popsat tím
defclass
příkladem...
V tom, ze prave neumoznuje napr. jednoduse odrolovat zasobnik.Aha, Go je mnohem dal s defer, nebot neumoznuje jednoduse odrolovat zasobnik. Prestavam chapat argumentaci timto smerem, zejmena s ohledem na implementaci contiguous stacku v Go od verze 1.4+.
ty efektivne implementovalo (napr. osekany defer).Defer v Go efektivni? Videl jste implementaci zde? Defer v Go neni deklarace, ale statement, ktery vytvari closure, kopiruje pro ni data, alokuje pamet v poolu a zamyka scheduler a to predtim nez se neco vubec stalo. Cely defer/panic/recover mechanismus ma nejen velky overhead, ale je nutne ho pouzivat v cele rade situaci, nebot v Go muze panikarit kde co a jiny mechanismus v podstate neni. Error handling v Go rozhodne neni vystavni kod.
A v tomto pripade povazuji implikaci jazyk poskytuje vyssi abstrakci by default => jazyk je dale za platnou.Pak mi opet neni jasne v cem mate vyhrady. Osetreni chyb zalozene na Conditions/Restarts, tak je implementovan v Lispu, poskytuje naopak vyssi miru abstrakce, nebot jedna se o generalizovane vyjimky a flexibilita je zajistena uplatnenim principu Separation of mechanism and policy, tedy oddelenim toho co ma byt udelano a jakym zpusobem to ma byt udelano. Osetreni chyb postavene na unwind-protect volajici clean-up kod po opusteni bloku ma minimalni overhead.
V pouzivani homoikonicity na zpracovani externich vstupu, jakkoliv toto muze zpocatku vypadat nadherne.Stale nechapu. Homoikonicky programovaci jazyk ma strukuru programu podobnou jeho syntaxi, coz umoznuje snadno transformovat kod i data stejnym zpusobem. Ale s tim jak se zpracovavaji data v programu z externich vstupu to nijak nesouvisi.
Ale s tim jak se zpracovavaji data v programu z externich vstupu to nijak nesouvisi.V realu souvisi az prilis, protoze to je presne to, co kazdeho napadne jako prvni a nejjednodussi vyuziti homoikonicity.
kazdy z nas chape pojem vyssi abstrakce v programovacim jazyce jinak - ja jako peclivy vyber nekolika malo konstrukci provedeny primo autory jazyka, Vy zase jako zpristupneni velkeho mnozstvi nizkourovnovych konstrukciAbsolutne ne, do teto roviny to nesmyslne posouvate pouze vy. Abstrakce je zpusob jak se designove vyporadat s komplexitou problemu a ja od programovaciho jazyka pouze ocekavam, ze mi poskytne dostatecne mnozstvi nastroju mnou zvolenou abstrakci implementovat. Pokud programovaci jazyk zacne vynucovat jediny zpusob, je to naopak cesta do pr**le, protoze neexistuje jedine spravne univerzalni reseni a drive ci pozdeji to zkonci podivnymi workaroundy. Lisp dava programatorovi vedle standardni datove a ridici abstrakce navic syntaxickou abstrakci a umoznujici, jak bylo zmineno, treba implementovat DSL s libovolnou urovni abstrakce.
Separation of mechanism and policy je hezke a naskyta se otazka, proc jazyk toto oddeleni nevynucuje, nybrz pouze doporucuje.Opet se v tom zacinam ztracet. Ted uz tedy neni problem mira abstrakce, ktera je fakticky vyssi nez u Go reseni, ale chybejici vynucovani necoho, co u Go implementace, ktera ma byt podle vas dale, neni. Podstatne je ze Lisp reseni dava programatorovi flexibilitu jak veci udelat a nebrani jinemu reseni, pokud je pro dany problem vhodne.
Dle meho nazoru by vysokourovnovy jazyk mel idiomaticke pouziti vynucovat. Lisp je z tohoto pohledu spise podobny ASM, tedy nizko-urovnovy.Ne. Vy opet chaoticky michate dohromady nekolik veci, minimalne expresivnost programovacicho jazyka a obsah a implementaci standardnich knihoven.
Dobre, ilustrujte mi na priklade uziti homoikonicity na zpracovani dat z externich vstupu, treba onech dat ze site - prvni co kazdeho napadne.Ale s tim jak se zpracovavaji data v programu z externich vstupu to nijak nesouvisi.V realu souvisi az prilis,
protoze to je presne to, co kazdeho napadne jako prvni a nejjednodussi vyuziti homoikonicity.Nebudte smesny, spise to posledni. Metaprogramovani zalozene na transformaci a generovani kodu vyzaduje specificky model mysleni, ktery si clovek nevytvori ze dne na den, a ktery lide prichazejicich z jinych jazyku, kde maximalne zavadi o limitovany template programming, proste nemaji.
Metaprogramovani zalozene na transformaci a generovani kodu vyzaduje specificky model mysleni, ktery si clovek nevytvori ze dne na den, a ktery lide prichazejicich z jinych jazyku, kde maximalne zavadi o limitovany template programming, proste nemaji.Jo. Být náckem hajlujícím na stadioně taky vyžaduje specifický model myšlení, který ostatní, kteří tak maximálně sedí někde v kanclu, prostě nemají.
vyignoroval jednu užitečnou strategii: Optimalizaci pro běžný případ.Nevyignoroval. Optimalizace je predevsim otazka implementace a Lisp standard dava pomerne slusny prostor pro specificke chovani s ohledem na "bezny pripad". To co je v jedne implementaci blok maker, muze byt v jine optimalizovana funkce napsana v assembleru, nektere veci jsou "optional" a nektere techniky se nedoporucuji. Tomu neunikne zadny jazyk.
Lisp má přesně opačný problém.Lisp ma plno problemu, nikdy to nebyl mainstreamovy jazyk, ale fakt je ze tu skoro 68 let a stale o nem slysime, je uspech.
Jo. Být náckem hajlujícím na stadioně taky vyžaduje specifický model myšlení, který ostatní, kteří tak maximálně sedí někde v kanclu, prostě nemají.To je velmi hloupe prirovnani - mozna ze i pres nej jste chytry a nemate problem ze dne na den zmenit paradigma, zacit v nem myslet a psat optimalni kod. Ale troufam si tvrdit, ze vetsina nas ostatnich, odkojena na prevazne imperativnich jazycich, s trochu funkcionalniho programovani, bude potrebovat cas.
To co je v jedne implementaci blok maker, muze byt v jine optimalizovana funkce napsana v assembleruMůže, ale tím se tak trochu popře to, že veškerý kód jsou s-exprs (viz #72 nebo #78) a že interpret je na 90 řádků. To samé ten argument o CLOS - ten taky nebude na 90 řádků, že...
To je velmi hloupe prirovnaniTo nemělo být ani tak přirovnání, chtěl jsem tím říct jen, že to, že něco vyžaduje jiný způsob myšlení, ještě neznamená, že to je lepší nebo že stojí za to myšlení měnit.
Může, ale tím se tak trochu popře to, že veškerý kód jsou s-exprs (viz #72 nebo #78) a že interpret je na 90 řádků.Znovu si prectete #72, kde jsem na konci psal:
Zbytek muze byt self modifikovatelny kod i kdyz v praxi je to omezeno na urovni standardni implementace z vykonostnich duvodu.Lisp muze byt implementovan bud jako kompilator, interpreter nebo oboji, a kompilovana verze omezi dynamicke chovani. Jak bylo ilustrovano v #117, behem prekladu se analyzuje kod a pouziva se nejoptimalnejsi zpusob, a to nevyjima ani jadro standardni implementace.
To samé ten argument o CLOS - ten taky nebude na 90 řádků, že...Nebude. Pointa byla v tom, ze pro implementaci Lispu vam staci napsat minimalni jadro v C/ASM/JS/Java ci cemkoliv jinem a zbytek samotneho Lispu muzete dodelat v Lispu samotnem, vcetne celeho CLOS. Takto je implementovan treba SBCL, kdy pouze runtime je implementovan v ASM/C, zbytek v Lisp, a i na urovni ASM/C se manipuluje s Lisp atomickymi symboly/s-expressions.
že to, že něco vyžaduje jiný způsob myšlení, ještě neznamená, že to je lepší nebo že stojí za to myšlení měnit.Souhlasim, ale to prece neni co jsem psal.
(desktop-size 1024 768) (bind key (alt f4) (close-window *active*)) ;; zavri aktivni okno (bind key (ctl alt f4) (apply minimize (find-window "FireFox"))) ;; najdi vsechna okna obsahujici FireFox a minimalizuje ;; pomocna funkce (dokaze toto xml?) (define (wine file) (exec "/usr/bin/wine" file)) (main-menu (item "FireFox" (exec "/usr/bin/firefox")) (menu "Office" (item "Word" (wine "C:\\Program Files\\Microsoft Office\\bin\Word.exe")) (item "Escel" (wine "C:\\Program Files\\Microsoft Office\\bin\Escel.exe")) ...))V tomto pripade by se ve skutecnosti nejednalo pouze o nejake konfiguracni hodnoty, ale fakticky o konfiguracni prikazy, ktere by menili nastaveni aplikace. Vyhoda o proti XML je v tom, ze se nemusis omezovat na to, co ti autor pridchystal za moznosti do XML a muzes zkombinovat jednotlive casti API (funkci) do novych, zajimavejsich celku, dle libosti.
Co tak tu konfiguraci zapsat misto XML pomoci S-vyrazu, ktere pujdou primo interpretovat?Na tomhle nápadu oceňuju nahrazení XML něčím rozumnějším. Tím to ale konči. Přímo interpretovat konfigurák mi přijde jako naprostá blbost, protože 1) člověk stejně musí reagovat na a ošetřovat syntaktické chyby, které uživatel udělá (a že je dřív nebo později udělá), 2) chyby uživatele mají potenciálně mnohem horší následky než u toho XML, protože mohou ovlivňovat program a 3) z bezpečnostního hlediska to je tragédie, viz třeba JSONp. Je samozřejmě otázka, jestli by to v dané aplikaci skutečně představovalo bezpečnostní problém, ale pravidlo palce je takové, že kód od uživatele pokud možno nespouštíme.
Na tomhle nápadu oceňuju nahrazení XML něčím rozumnějším.To je imho do velké míry nemožné. Já byl docela XML hater, ale poté co jsem si o tom kvůli práci nastudoval víc literatury musím uznat, že cokoliv co by mohlo nahradit XML by skončilo úplně stejně komplikované. Možná by šla trochu vylepšit syntaxe, ale i u tohohle vcelku pochybuji, protože s-vyrazy by byly možná ještě o kus delší. Co dodneška nesnáším je javovský ekosystém kolem XML, ten by si fakt nahradit zasloužil.
Kdysi kdosi prohlásil, že všechny jazyky konvergují k Lispu. A víceméně to sedí.Imho konfirmační bias. Ano, dají se najít vlastnosti nových jazyků nebo nových verzí starých jazyků, které tohle tvrzení podporují, ale stejně tak imho pozorujeme i vlastnosti tomu odporující. Viz třeba JS Harmony, ten jde imho opačným směrem. A v neposlední řadě to je imho vidět na Lispu samotném, novější & populární varianty Lispu, tj. mám na mysli hlavně CommonLisp a Clojure, jdou od původní minimalističnosti směrem ke klasickým jazykům.
Rust teda žádný zázrak není, to už je mnohem zajímavější Go.Go nemá generika (až na pár speciálních typů, které jsou integrovány přímo v jazyce) - je tedy téměř nepoužitelné. A to, jak je v něm implementován strukturální podtypový polymorfismus (kopírováním vtable), se mi také příliš nelíbí.
Go nemá generika (až na pár speciálních typů, které jsou integrovány přímo v jazyce)Pracuje se na tom a zatim nevedi jak to rozumne udelat.
je tedy téměř nepoužitelné.Rekl bych ze plno projektu v produkcnim stavu napsanem v Go ukazuje ze to neni pravda.
Rust uz je v podstate na stejne trajektorii jako jazyk D.IMHO má lepší výchozí předpoklady - není to pouze re-engineering (resp. osobně bych spíš řekl re-over-engineering) C++ a od začátku má testovací zátěžový seriózní projekt (Servo), ale máš do jisté míry pravdu, bohužel to tak trochu vypadá.
podstatne je dotahnout to do nejakeho pouzitelneho stavu.Coz nastesti Dao je. Skoda, ze dnes jiz i skveli programatori hodnoti projekty podle krasy webovych stranek :( Ohledne jazyka Nemerle, tak skoda, ze vychazi z bajtkodu CLI, protoze ten je prilis omezeny a diky tomu virtualni masiny nepodporuji napr. zcela nezavisle paralelni zpracovani. Jinymi slovy se jedna o dalsi omalovanku, ktera skonci na urovni C#/Javy a nikdy nevybehne z uzavreneho boxu narozdil napr. od Dao.
Coz nastesti Dao je. Skoda, ze dnes jiz i skveli programatori hodnoti projekty podle krasy webovych stranek :(Já tedy nejsem skvělý programátor, takže nehodnotím podle krásy, ale podle nekonzistencí. Působí to prostě sloppy a ne důvěryhodně na něco, co po mě chce takové životní rozhodnutní, jako věnovat čas a energii programovacímu jazyku, který mě potom má třeba živit.