<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>informatica &#8211; Untitled #1</title>
	<atom:link href="https://atlog.it/blog/archives/category/informatica/feed" rel="self" type="application/rss+xml" />
	<link>https://atlog.it/blog</link>
	<description></description>
	<lastBuildDate>Tue, 06 Jan 2026 17:30:40 +0000</lastBuildDate>
	<language>it-IT</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>
	<item>
		<title>Lo zen e l&#8217;arte della manutenzione della cartella home (parte 1)</title>
		<link>https://atlog.it/blog/archives/1343</link>
					<comments>https://atlog.it/blog/archives/1343#respond</comments>
		
		<dc:creator><![CDATA[alberto]]></dc:creator>
		<pubDate>Tue, 06 Jan 2026 17:30:40 +0000</pubDate>
				<category><![CDATA[informatica]]></category>
		<category><![CDATA[linux]]></category>
		<guid isPermaLink="false">https://atlog.it/blog/?p=1343</guid>

					<description><![CDATA[Gli utenti Linux (o Unix in generale) hanno una relazione personale con la loro cartella home: è un po&#8217; l&#8217;equivalente del desktop per i sistemi Windows, il posto dove si mettono le cose &#8220;di default&#8221; in attesa di sistemarle nella loro collocazione definitiva (cosa che può anche non succedere mai, ma questo è un altro &#8230; ]]></description>
										<content:encoded><![CDATA[<p>Gli utenti Linux (o Unix in generale) hanno una relazione personale con la loro cartella <em>home</em>: è un po&#8217; l&#8217;equivalente del desktop per i sistemi Windows, il posto dove si mettono le cose &#8220;di default&#8221; in attesa di sistemarle nella loro collocazione definitiva (cosa che può anche non succedere mai, ma questo è un altro discorso).<span id="more-1343"></span></p>
<p>Ne segue la ben nota tendenza ad accogliere ciarpame di ogni genere, che fa bella mostra di sé ad ogni successiva esecuzione di <strong>ls</strong>. Ma come dovrebbe essere una home &#8220;ben tenuta&#8221;? Secondo me, le regole di base sono due:</p>
<ul>
<li>niente file (o il minimo indispensabile), solo directory, e</li>
<li>un massimo di 10/12 elementi, in modo da non superare le due/tre righe di output di ls (in un terminale di dimensioni sensate).</li>
</ul>
<p>Purtroppo, la recente evoluzione delle distribuzioni Linux sta andando decisamente contro a questo mio ideale di ordine. Ecco infatti come appare la home directory di un sistema appena installato:</p>
<p><a href="https://atlog.it/blog/wp-content/uploads/2026/01/img.png"><img decoding="async" class="aligncenter size-large wp-image-1346" src="https://atlog.it/blog/wp-content/uploads/2026/01/img-1024x178.png" alt="Output del comando ls nella home di un sistema appena installato" width="1024" height="178" srcset="https://atlog.it/blog/wp-content/uploads/2026/01/img-1024x178.png 1024w, https://atlog.it/blog/wp-content/uploads/2026/01/img-300x52.png 300w, https://atlog.it/blog/wp-content/uploads/2026/01/img-768x134.png 768w, https://atlog.it/blog/wp-content/uploads/2026/01/img.png 1080w" sizes="(max-width: 1024px) 100vw, 1024px" /></a>Non abbiamo nemmeno iniziato a caricare i nostri dati che già l&#8217;installer ha &#8220;opportunamente&#8221; pensato di creare una manciata di cartelle di dubbia utilità. Il problema è che queste cartelle non si possono semplicemente cancellare, perché sono memorizzate come percorsi di default per certe applicazioni che quindi, non trovandole, potrebbero giustamente lamentarsi o, peggio ancora, ricrearle autonomamente ogni volta.</p>
<p>Che fare, dunque? La mia personalissima analisi di queste cartelle di default è la seguente:</p>
<ul>
<li>Desktop: questa me la devo tenere, anche se personalmente la uso pochissimo (che senso ha mettere delle icone in un posto che è quasi sempre coperto al 90% dalle finestre?), ma il window manager la tratta in maniera speciale e non sarebbe opportuno unirla a un&#8217;altra</li>
<li>Documents: magari a qualcuno serve, per me è totalmente inutile (i miei documenti li organizzo come credo io, non certo mettendo tutto in un&#8217;unica directory); una pessima scoppiazzatura dal mondo Windows</li>
<li>Downloads: questa è effettivamente una buona idea, mettere di default i file scaricati qui contribuisce ad evitare l&#8217;effetto &#8220;ciarpame nella home&#8221; menzionato sopra</li>
<li>Music, Pictures, Videos: anche queste sono utili per fare ordine, volendo si potrebbero unire in un&#8217;unica cartella &#8220;Media&#8221; ma a volte è meglio averle separate (ad es. per le ricerche su un solo tipo di media)</li>
<li>Public: totalmente inutile se non avete condivisioni di rete</li>
<li>Templates: non uso programmi che sfruttino questa directory, quindi inutile anch&#8217;essa</li>
</ul>
<p>Riassumendo, almeno 3 cartelle su 8 sono del tutto inutili, e sarebbe bello liberarsene. Come fare? La chiave sta nel file <code>.config/user-dirs.dirs</code>, che contiene l&#8217;associazione tra i &#8220;ruoli&#8221; che queste directory svolgono nel sistema e il loro percorso su disco. Fortunatamente non è necessario che questa associazione sia biunivoca, quindi è possibile far svolgere a un&#8217;unica directory più ruoli. Ad esempio per unificare Documents e Downloads basta modificare il file summenzionato come segue:</p>
<pre>XDG_DOWNLOAD_DIR="$HOME/Downloads"
XDG_DOCUMENTS_DIR="$HOME/Downloads"</pre>
<p>oppure, per unificare Music, Pictures e Video nell&#8217;unica cartella Media:</p>
<pre>XDG_MUSIC_DIR="$HOME/Media"
XDG_PICTURES_DIR="$HOME/Media"
XDG_VIDEOS_DIR="$HOME/Media"</pre>
<p>Se infine vogliamo solo nascondere una cartella che non ci serve (ad es. Public) in modo tale che non appaia più nell&#8217;elenco dei file, ma senza identificarla con altre, la soluzione migliore è rinominarla in modo tale da farla diventare nascosta (ad es. da <code>Public</code> a <code>.Public</code>), e modificare di conseguenza la linea corrispondente:</p>
<pre>XDG_PUBLICSHARE_DIR="$HOME/.Public"</pre>
<p>Niente male, no? In questo modo abbiamo subito una home molto più ordinata, e possiamo procedere a riempirla senza remore con le nostre schifezze.</p>
<p>Ma parlando di schifezze&#8230; cos&#8217;altro c&#8217;è nella home di un sistema appena installato? Nient&#8217;altro di visibile, d&#8217;accordo, ma che dire dei file nascosti? Sarà l&#8217;argomento della prossima (e ultima&#8230;) puntata!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://atlog.it/blog/archives/1343/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>La contrazione dei tempi è reale&#8230;</title>
		<link>https://atlog.it/blog/archives/1283</link>
		
		<dc:creator><![CDATA[alberto]]></dc:creator>
		<pubDate>Sat, 01 Mar 2025 17:43:48 +0000</pubDate>
				<category><![CDATA[informatica]]></category>
		<category><![CDATA[stato del mondo]]></category>
		<guid isPermaLink="false">https://atlog.it/blog/?p=1283</guid>

					<description><![CDATA[&#8230;e apparentemente non serve neanche viaggiare a velocità relativistiche, basta partecipare a una riunione su Google Meet stando ben fermi nel proprio ufficio: Rimango sempre affascinato da come i giganti informatici del XXI secolo come Google Alphabet siano in grado di sviluppare software enormemente complessi (e che funzionano generalmente bene) in cui però anche l&#8217;effettuare &#8230; ]]></description>
										<content:encoded><![CDATA[<p>&#8230;e apparentemente non serve neanche viaggiare a velocità relativistiche, basta partecipare a una riunione su Google Meet stando ben fermi nel proprio ufficio:<span id="more-1283"></span></p>
<figure id="attachment_1284" aria-describedby="caption-attachment-1284" style="width: 398px" class="wp-caption aligncenter"><a href="https://atlog.it/blog/wp-content/uploads/2025/02/riunione.png"><img decoding="async" class="wp-image-1284 size-full" src="https://atlog.it/blog/wp-content/uploads/2025/02/riunione.png" alt="Una tabella con durata e orari di partecipazione a una riunione; la terza riga riporta una durata di 23 minuti con partecipazione dalle 11:16 alle 11:52" width="398" height="185" srcset="https://atlog.it/blog/wp-content/uploads/2025/02/riunione.png 398w, https://atlog.it/blog/wp-content/uploads/2025/02/riunione-300x139.png 300w" sizes="(max-width: 398px) 100vw, 398px" /></a><figcaption id="caption-attachment-1284" class="wp-caption-text">Seriously, Google?</figcaption></figure>
<p>Rimango sempre affascinato da come i giganti informatici del XXI secolo come <del>Google</del> Alphabet siano in grado di sviluppare software enormemente complessi (e che funzionano generalmente bene) in cui però anche l&#8217;effettuare correttamente una innocua sottrazione si può rivelare, talvolta, un problema insolubile.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Computer e musei non vanno d&#8217;accordo</title>
		<link>https://atlog.it/blog/archives/1229</link>
		
		<dc:creator><![CDATA[alberto]]></dc:creator>
		<pubDate>Wed, 26 Jun 2024 21:13:03 +0000</pubDate>
				<category><![CDATA[informatica]]></category>
		<category><![CDATA[recriminazioni inutili]]></category>
		<guid isPermaLink="false">https://atlog.it/blog/?p=1229</guid>

					<description><![CDATA[Penso sia ormai diventato evidente che l&#8217;invenzione del calcolatore elettronico (volgamente detto computer) a metà del Novecento debba essere considerata come uno dei punti di svolta nella storia dell&#8217;umanità. L&#8217;importanza dei computer nella società moderna è indiscutibile, e (a meno di catastrofi) non farà che aumentare nel futuro. In ragione di tale importanza, sembra naturale &#8230; ]]></description>
										<content:encoded><![CDATA[<p>Penso sia ormai diventato evidente che l&#8217;invenzione del calcolatore elettronico (volgamente detto computer) a metà del Novecento debba essere considerata come uno dei punti di svolta nella storia dell&#8217;umanità. L&#8217;importanza dei computer nella società moderna è indiscutibile, e (a meno di catastrofi) non farà che aumentare nel futuro. In ragione di tale importanza, sembra naturale fare qualcosa per preservare almeno alcuni di questi oggetti, la cui storia tra l&#8217;altro è sempre stata caratterizzata da un&#8217;evoluzione rapidissima.</p>
<p><span id="more-1229"></span>Per questo motivo iniziative come quella lanciata dal cofondatore di Microsoft <a href="https://en.wikipedia.org/wiki/Paul_Allen" target="_blank" rel="noopener">Paul Allen</a> sono particolarmente importanti. Nel 2006, infatti, Allen ebbe l&#8217;idea di mettere a disposizione del pubblico la sua collezione di computer storici (e ancora funzionanti), dapprima tramite accesso remoto (via <a href="https://en.wikipedia.org/wiki/Telnet" target="_blank" rel="noopener">telnet</a>) e poi, a partire dal 2012, anche di persona, con l&#8217;apertura del <a href="https://en.wikipedia.org/wiki/Living_Computers:_Museum_%2B_Labs" target="_blank" rel="noopener">Living Computer Museum</a> (&#8220;Museo dei computer viventi&#8221;; già il nome è tutto un programma) a Seattle, la sua città e — non per caso — una delle capitali mondiali dell&#8217;informatica.</p>
<p>Il museo, che si è poi ingrandito nel tempo grazie a varie donazioni successive, era l&#8217;unico posto al mondo in cui si potevano osservare e (ancora più importante) <em>operare</em> esemplari originali e perfettamente funzionanti di alcuni tra gli elaboratori che hanno fatto la storia dell&#8217;informatica, tra cui il <a href="https://en.wikipedia.org/wiki/PDP-10">PDP-10</a> della DEC (primo computer usato da Allen e Gates), vari mainframe della linea <a href="https://en.wikipedia.org/wiki/IBM_System/360" target="_blank" rel="noopener">System/360</a> della IBM, il mitico <a href="https://en.wikipedia.org/wiki/Xerox_Alto" target="_blank" rel="noopener">Xerox Alto</a>, i primi microcomputer della Apple (l&#8217;<a href="https://en.wikipedia.org/wiki/Apple_II" target="_blank" rel="noopener">Apple II</a> su tutti) e della IBM (tra cui il primo e unico <a href="https://en.wikipedia.org/wiki/IBM_Personal_Computer" target="_blank" rel="noopener">Personal Computer</a>), e molti altri ancora.</p>
<p>Purtroppo i verbi coniugati al passato sono d&#8217;obbligo: nel frattempo infatti Allen è morto (nell&#8217;ottobre del 2018) e il museo (le cui spese di gestione non erano probabilmente coperte nemmeno lontanamente dagli incassi) ha chiuso i battenti nel febbraio del 2020, con la &#8220;scusa&#8221; della pandemia da COVID-19, e non ha mai più riaperto. <a href="https://www.geekwire.com/2024/seattles-living-computers-museum-logs-off-for-good-as-paul-allen-estate-will-auction-vintage-items/" target="_blank" rel="noopener">È notizia di questi giorni</a> che la chiusura è a tutti gli effetti permanente, e che parte del materiale esposto (almeno 150 pezzi) sarà messo all&#8217;asta alla celebre casa d&#8217;aste Christie&#8217;s.</p>
<p>Al di là del fatto che, come <a href="http://oldvcr.blogspot.com/2024/06/the-living-computers-museum-finally-isnt.html" target="_blank" rel="noopener">qualcuno ha giustamente osservato</a>, non è esattamente elegantissimo vendere all&#8217;asta del materiale che è stato donato a un museo con l&#8217;idea che rimanesse in quel museo (anche se è stato annunciato che i proventi andranno in beneficenza), la cosa veramente sconfortante è il fallimento dell&#8217;idea stessa. Se nemmeno uno degli uomini più ricchi del mondo è in grado di costruire un&#8217;istituzione che permetta di continuare a operare questi oggetti che hanno avuto un ruolo così importante nell&#8217;evoluzione della tecnica umana, che speranze possiamo avere sul fatto che qualcun altro ci riesca?</p>
<p><strong>Aggiornamento (27/06)</strong>: <a href="https://news.ycombinator.com/item?id=40789179" target="_blank" rel="noopener">discussione dell&#8217;annuncio su Hacker News</a>. Secondo <a href="http://canonical.org/~kragen/" target="_blank" rel="noopener">Kragen Sitaker</a>, il PDP-10 che era ospitato nel LCM era l&#8217;ultimo esemplare ancora funzionante al mondo. In quanto <a href="https://en.wikipedia.org/wiki/Emacs" target="_blank" rel="noopener">Emacs</a>iano di lunga data, mi scende la lacrimuccia.</p>
<p><strong>Aggiornamento (19/08)</strong>: Jason Scott fornisce <a href="http://ascii.textfiles.com/archives/5672" target="_blank" rel="noopener">altre informazioni interessanti</a> su tutta la vicenda.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Speedrunning Software Foundations volume 1</title>
		<link>https://atlog.it/blog/archives/1217</link>
		
		<dc:creator><![CDATA[alberto]]></dc:creator>
		<pubDate>Tue, 30 Apr 2024 16:55:16 +0000</pubDate>
				<category><![CDATA[informatica]]></category>
		<category><![CDATA[vita vissuta]]></category>
		<guid isPermaLink="false">https://atlog.it/blog/?p=1217</guid>

					<description><![CDATA[A volte mi capita di iniziare un lavoro, dopo un po&#8217; notare una qualche regolarità in quello che sto facendo, e pensare: «non avrebbe alcun senso proseguire imponendosi di mantenere questa regola che è emersa in maniera del tutto casuale dal modo in cui ho lavorato fino ad adesso&#8230; quindi facciamolo!». (Sì, lo so, sono &#8230; ]]></description>
										<content:encoded><![CDATA[<p>A volte mi capita di iniziare un lavoro, dopo un po&#8217; notare una qualche regolarità in quello che sto facendo, e pensare: «non avrebbe alcun senso proseguire imponendosi di mantenere questa regola che è emersa in maniera del tutto casuale dal modo in cui ho lavorato fino ad adesso&#8230; quindi facciamolo!». (Sì, lo so, sono un tipo un po&#8217; strano.)</p>
<p><span id="more-1217"></span></p>
<p>Nello specifico ci sono ricascato una decina di giorni fa, quando, dovendo riprendere un po&#8217;  di dimestichezza con il proof assistant (&#8220;assistente dimostrativo&#8221;?) <a href="https://coq.inria.fr/" target="_blank" rel="noopener">Coq</a>, ho deciso di leggermi il primo volume di <a href="https://softwarefoundations.cis.upenn.edu/" target="_blank" rel="noopener">Software Foundations</a>. Per chi non lo sapesse (ovvero &#8212; a naso &#8212; il 99,9999% della popolazione mondiale), si tratta di un corso sui fondamenti logici della programmazione con la peculiare caratteristica di essere completamente formalizzato (nel <a href="https://en.wikipedia.org/wiki/Calculus_of_constructions" target="_blank" rel="noopener">calcolo delle costruzioni induttive</a>, che è appunto la teoria implementata da Coq). Ah, e per la cronaca è anche (gratuito e) liberamente disponibile dal sito sopra linkato.</p>
<p>La cosa era partita, giovedì 18 Aprile, in maniera del tutto innocente, ovvero scaricando l&#8217;archivio con i sorgenti del libro, spacchettandolo e iniziando a leggere (e a fare gli esercizi incorporati nel testo). La domenica mi accorgo che, bene o male, stavo riuscendo a tenere il ritmo di un capitolo al giorno, compatibilmente con gli altri impegni che avevo. Per cui mi sono detto: perché non provare a continuare così fino alla fine? La settimana dopo ci sarebbe oltretutto stato il ponte del 25 aprile, quindi la cosa non sembrava completamente impossibile.</p>
<p><a href="https://atlog.it/blog/wp-content/uploads/2024/04/speedrun.png"><img loading="lazy" decoding="async" class="size-large wp-image-1219 alignnone" src="https://atlog.it/blog/wp-content/uploads/2024/04/speedrun-1024x447.png" alt="La lista dei capitoli di Software Foundations, con data di ultima modifica" width="1024" height="447" srcset="https://atlog.it/blog/wp-content/uploads/2024/04/speedrun-1024x447.png 1024w, https://atlog.it/blog/wp-content/uploads/2024/04/speedrun-300x131.png 300w, https://atlog.it/blog/wp-content/uploads/2024/04/speedrun-768x335.png 768w, https://atlog.it/blog/wp-content/uploads/2024/04/speedrun.png 1050w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Per farla breve, i risultati li vedete nello screenshot qui sopra: tutto sommato direi che lo speedrun è effettivamente riuscito, con l&#8217;eccezione del capitolo <code>IndProp</code> che ha richiesto due giorni e peraltro, come potrà testimoniare chiunque abbia fatto il corso, contiene sostanzialmente il doppio del materiale del capitolo medio. (I capitoli in fondo, quelli che non ho modificato, sono opzionali, anche se conto di fare pure quelli.)</p>
<p>Ma gli esercizi, direte voi?</p>
<p><a href="https://atlog.it/blog/wp-content/uploads/2024/04/admitted.png"><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-1220" src="https://atlog.it/blog/wp-content/uploads/2024/04/admitted-1024x447.png" alt="Resoconto degli esercizi saltati" width="1024" height="447" srcset="https://atlog.it/blog/wp-content/uploads/2024/04/admitted-1024x447.png 1024w, https://atlog.it/blog/wp-content/uploads/2024/04/admitted-300x131.png 300w, https://atlog.it/blog/wp-content/uploads/2024/04/admitted-768x335.png 768w, https://atlog.it/blog/wp-content/uploads/2024/04/admitted.png 1050w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Quasi tutti ok, come si può notare dal resoconto qui sopra. (Il comando <code>Admitted.</code> è quello che si usa all&#8217;interno di una dimostrazione per dire a Coq «basta, non ne posso più, va&#8217; a quel paese e fammi andare avanti». Più o meno.) Con l&#8217;eccezione di alcuni esercizi inutilmente noiosi su cui non sono stato a perdere tempo (in <code>Induction</code> e in <code>Logic</code>; i match in <code>Basics</code> sono spurii), gli unici che mancano sono in <code>IndProp</code> e in <code>Imp</code>, e riguardano comunque parti opzionali e/o addizionali (su cui comunque conto di ritornare con più calma).</p>
<p>Mica male, no? E adesso sotto con il volume 2, dove inizia la parte più interessante; ma stavolta senza vincoli di tempo, perché un bel gioco dura poco!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Mettere su un sistema dual-boot nel 2024</title>
		<link>https://atlog.it/blog/archives/1196</link>
		
		<dc:creator><![CDATA[alberto]]></dc:creator>
		<pubDate>Wed, 28 Feb 2024 22:14:31 +0000</pubDate>
				<category><![CDATA[informatica]]></category>
		<guid isPermaLink="false">https://atlog.it/blog/?p=1196</guid>

					<description><![CDATA[Recentemente mi sono trovato a disporre, per la prima volta in una decina di anni, di un PC con Windows (pre)installato. Si tratta nientemeno che dell&#8217;ultimissima <a href="https://en.wikipedia.org/wiki/Windows_11" target="_blank" rel="noopener">versione 11</a> , e la domanda è sorta subito spontanea: sarà ancora possibile far coabitare Windows e Linux su una stessa macchina, un rito di passaggio che hanno attraversato tanti informatici &#8230; ]]></description>
										<content:encoded><![CDATA[<p>Recentemente mi sono trovato a disporre, per la prima volta in una decina di anni, di un PC con Windows (pre)installato. Si tratta nientemeno che dell&#8217;ultimissima <a href="https://en.wikipedia.org/wiki/Windows_11" target="_blank" rel="noopener">versione 11</a>, e la domanda è sorta subito spontanea: sarà ancora possibile far coabitare Windows e Linux su una stessa macchina, un rito di passaggio che hanno attraversato tanti informatici (me compreso) negli anni &#8217;90 e &#8217;00?<span id="more-1196"></span> Il dubbio è più che lecito, vista la notoria — e decennale — <a href="https://en.wikipedia.org/wiki/Halloween_documents" target="_blank" rel="noopener">avversione della Microsoft verso il software libero</a> in generale, e i sistemi operativi alternativi a Windows in particolare.</p>
<p>Ebbene, vi annuncio con grande gioia che sì, è ancora possibile mettere su un sistema dual boot nel 2024, ma ci sono (ovviamente) alcune trappole disposte sul cammino che è necessario evitare per non complicarsi la vita oltremodo. Siccome online ho trovato un sacco di informazioni obsolete e/o fuorvianti, ho pensato di riassumere i passaggi principali in un post, che mi auguro possa servire da riferimento ad altri sventurati che decidessero di intraprendere questa strada (compreso, eventualmente, me stesso nel futuro).</p>
<p>Naturalmente è necessario che l&#8217;hardware di cui disponete sia supportato dalla versione più recente del kernel Linux; questo purtroppo non è un dato scontato (oggi come nel 1998&#8230;), ma è facilmente verificabile prima di procedere su appositi siti come il glorioso <a href="https://linux-on-laptops.com/" target="_blank" rel="noopener">linux on laptops</a> o sui siti delle varie distribuzioni (ad esempio <a href="https://wiki.debian.org/InstallingDebianOn/" target="_blank" rel="noopener">qui</a> per Debian, la mia distro di riferimento). Io non ho avuto problemi da questo punto di vista: il PC che ho usato infatti è uno <a href="https://en.wikipedia.org/wiki/ThinkPad" target="_blank" rel="noopener">Thinkpad</a> della Lenovo, linea di portatili nota per l&#8217;ottima compatibilità del loro hardware con Linux.</p>
<p>Anzitutto sgombriamo il campo da un primo equivoco: <strong>non è più necessario disabilitare lo UEFI Secure Boot per installare Linux nel 2024</strong>. Molte guide online affermano il contrario, ma è da almeno cinque anni che tutte le maggiori distribuzioni sono in grado di gestire il SB senza problemi, grazie a uno <a href="https://en.wikipedia.org/wiki/Shim_(computing)" target="_blank" rel="noopener">shim</a> sviluppato originariamente da Ubuntu. La cosa è importante perché il Secure Boot funge da <em>root of trust</em> per il sistema, e alcune applicazioni possono rifiutarsi di funzionare su sistemi in cui esso è disabilitato.</p>
<p>Nessun problema da questo punto di vista, quindi? Non proprio: alcune marche (tra cui, neanche a dirlo, Lenovo&#8230;) hanno pensato bene di <em>vietare di default l&#8217;uso del Secure Boot da parte di software che non sia firmato dalla chiave privata della Microsoft</em> (!!). Per questo motivo potrebbe dover essere necessario entrare nel menu di boot e abilitare esplicitamente questa possibilità, come descritto ad esempio da Lenovo in <a href="https://download.lenovo.com/pccbbs/mobiles_pdf/Enable_Secure_Boot_for_Linux_Secured-core_PCs.pdf" target="_blank" rel="noopener">questo documento</a>.</p>
<p>Superato questo primo ostacolo diventa tecnicamente possibile scaricare una immagine ISO della vostra distribuzione preferita, copiarla su una pennetta USB (usando i soliti metodi ben documentati) e procedere all&#8217;installazione (se necessario, abilitando l&#8217;avvio da USB nel solito menu di boot). Ma prima di farlo è opportuno disinnescare altre due mine proditoriamente piazzate dalla Microsoft.</p>
<ol>
<li>La prima mina si chiama <em>Bitlocker</em>, nel caso fosse attivo (lo è di default nell&#8217;edizione Pro di Windows, cosa che ovviamente ignoravo). Trattandosi di un sistema di crittazione del disco rigido, non gli vanno molto a genio le modifiche fatte alle sue spalle, ragion per cui, se non lo disabilitate, <strong>ad ogni riavvio</strong> Windows si bloccherà chiedendovi di immettere una <em>recovery key</em> per sbloccare il vostro prezioso volume. Questa recovery key si può recuperare (ehm&#8230;) utilizzando l&#8217;account Microsoft che è stato associato al PC in fase di installazione; eggià, perché nel 2024 è diventato impossibile usare un computer senza avere (accesso a internet e) un account Microsoft.<br />
(Sì, lo so che volendo è possibile <a href="https://www.tomshardware.com/how-to/install-windows-11-without-microsoft-account" target="_blank" rel="noopener">installare Windows eludendo la richiesta di creare un account</a>, ma realisticamente, quante persone si prenderanno il disturbo di farlo?)<br />
((Peraltro, per una volta mi sento di dover ringraziare la MS: grazie a questa esperienza ho potuto provare, seppur in maniera surrogata, l&#8217;emozione indubbiamente notevole di essere oggetto di un <a href="https://en.wikipedia.org/wiki/Ransomware" target="_blank" rel="noopener">attacco ransomware</a>.))</li>
<li>La seconda mina si chiama <em>Fast Startup</em>, anch&#8217;esso attivo di default; si tratta di un sistema per ridurre i tempi di avvio di Windows che, essenzialmente, invece di spegnere il PC quando gli dite di farlo lo manda in ibernazione. In questo caso il sintomo non è così traumatico (Windows si limita a notare all&#8217;avvio che il PIN che avevate inserito non è più valido, e vi chiede di immetterne un altro), ma è comunque fastidioso, motivo per cui è opportuno <a href="https://support.lenovo.com/it/it/solutions/ht513773-how-to-enable-or-disable-fast-startup-on-windows-11" target="_blank" rel="noopener">disabilitare la “feature” una volta per tutte</a>, specialmente se avviate Windows una volta ogni morte di papa.</li>
</ol>
<p>A questo punto ogni ostacolo è rimosso, e si può procedere con l&#8217;installazione. Se l&#8217;installer è fatto bene, dovrebbe permettervi di ridimensionare la partizione di Windows per fare spazio a Linux; quando sarà il momento di decidere le dimensioni, tenete presente che la partizione Windows sarà accessibile da Linux ma non viceversa, per cui può essere opportuno lasciare un po&#8217; più di margine alla partizione Windows (ma ovviamente tutto dipende dall&#8217;uso che verrà fatto dei due sistemi).</p>
<p>Infine, alcuni consigli specifici per Debian:</p>
<ul>
<li>Usate l&#8217;immagine <strong>netinst</strong> se avete un accesso di rete “facile”, cioè tramite cavo ethernet oppure via wi-fi (controllate che la vostra scheda sia supportata dal kernel!), ma solo in caso di autenticazione tramite chiave condivisa (PSK); metodi di autenticazione più sofisticati non sono al momento supportati da <code>debian-installer</code>.</li>
<li>In caso contrario conviene scaricare una immagine più corposa, che vi permetterà di mettere in piedi un sistema ragionevolmente completo senza accesso a internet; quest&#8217;ultimo potrà poi essere configurato successivamente con calma.</li>
</ul>
<p>Se tutto va bene, nell&#8217;arco di una mezz&#8217;oretta avrete il vostro sistema dual-boot bello e pronto. Per sicurezza si può far girare <code>chkdsk.exe</code> sulla partizione Windows, giusto per verificare che l&#8217;aver rimpicciolito la partizione di Windows non abbia prodotto danni (ma non dovrebbe).</p>
<p><a href="https://en.wikipedia.org/wiki/Yes,_Virginia,_there_is_a_Santa_Claus" target="_blank" rel="noopener">Yes, Virginia, there is a Santa Claus</a>!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Compilatori degni di nota</title>
		<link>https://atlog.it/blog/archives/1047</link>
		
		<dc:creator><![CDATA[alberto]]></dc:creator>
		<pubDate>Sat, 13 May 2017 17:25:36 +0000</pubDate>
				<category><![CDATA[informatica]]></category>
		<guid isPermaLink="false">http://atlog.it/blog/?p=1047</guid>

					<description><![CDATA[Sono gemme come <a href="http://tom7.org/abc/paper.pdf" target="_blank" rel="noopener noreferrer">questo articolo</a> (e relativo <a href="https://www.youtube.com/watch?v=LA_DrBwkiJA" target="_blank" rel="noopener noreferrer">video esplicativo</a> ) che ti fanno ritornare il sorriso in una giornata partita male. Gli esperti di <a href="https://en.wikipedia.org/wiki/Esoteric_programming_language" target="_blank" rel="noopener noreferrer">programmazione esoterica</a> riconosceranno nel sottoinsieme di istruzioni x86 utilizzate dal tizio qualcosa di simile a una <a href="https://en.wikipedia.org/wiki/One_instruction_set_computer" target="_blank" rel="noopener noreferrer">macchina a una istruzione</a> del tipo subtract and branch if negative, vista la disponibilità di SUB, CMP e Jxx, ma le pesanti limitazioni sui metodi &#8230; ]]></description>
										<content:encoded><![CDATA[<p>Sono gemme come <a href="http://tom7.org/abc/paper.pdf" target="_blank" rel="noopener noreferrer">questo articolo</a> (e relativo <a href="https://www.youtube.com/watch?v=LA_DrBwkiJA" target="_blank" rel="noopener noreferrer">video esplicativo</a>) che ti fanno ritornare il sorriso in una giornata partita male.</p>
<p>Gli esperti di <a href="https://en.wikipedia.org/wiki/Esoteric_programming_language" target="_blank" rel="noopener noreferrer">programmazione esoterica</a> riconosceranno nel sottoinsieme di istruzioni x86 utilizzate dal tizio qualcosa di simile a una <a href="https://en.wikipedia.org/wiki/One_instruction_set_computer" target="_blank" rel="noopener noreferrer">macchina a una istruzione</a> del tipo <em>subtract and branch if negative</em>, vista la disponibilità di SUB, CMP e Jxx, ma le pesanti limitazioni sui metodi di addressing rendono tutto notevolmente più complicato, per non parlare del vincolo sull&#8217;assenza di codice auto-modificantesi. Davvero ben fatto!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>I primi passi di una rivoluzione silenziosa</title>
		<link>https://atlog.it/blog/archives/681</link>
		
		<dc:creator><![CDATA[alberto]]></dc:creator>
		<pubDate>Mon, 19 Aug 2013 02:41:52 +0000</pubDate>
				<category><![CDATA[fisica]]></category>
		<category><![CDATA[informatica]]></category>
		<category><![CDATA[web]]></category>
		<guid isPermaLink="false">http://timeisntonmyside.wordpress.com/?p=681</guid>

					<description><![CDATA[Esattamente 22 anni fa entrava in funzione un servizio destinato a rivoluzionare il mondo della ricerca. Sto parlando dell&#8217; <a href="http://arxiv.org/">arXiv</a> , un archivio di articoli scientifici (pubblicati o in versione preliminare) caratterizzato dal fatto di essere ad accesso totalmente libero per chiunque. Per avere un&#8217;idea delle sue dimensioni attuali non c&#8217;è modo migliore di dare un&#8217;occhiata &#8230; ]]></description>
										<content:encoded><![CDATA[<p>Esattamente 22 anni fa entrava in funzione un servizio destinato a rivoluzionare il mondo della ricerca. Sto parlando dell&#8217;<a href="http://arxiv.org/">arXiv</a>, un archivio di articoli scientifici (pubblicati o in versione preliminare) caratterizzato dal fatto di essere ad accesso totalmente libero per chiunque. Per avere un&#8217;idea delle sue dimensioni attuali non c&#8217;è modo migliore di dare un&#8217;occhiata all&#8217;incredibile mappa interattiva che è stata prodotta dal <a href="http://paperscape.org">progetto paperscape</a>:</p>
<figure id="attachment_872" aria-describedby="caption-attachment-872" style="width: 450px" class="wp-caption aligncenter"><a href="http://atlog.it/blog/wp-content/uploads/2013/08/map.png"><img loading="lazy" decoding="async" class="size-full wp-image-872" alt="Mappa dell'arXiv" src="http://atlog.it/blog/wp-content/uploads/2013/08/map.png" width="450" height="300" srcset="https://atlog.it/blog/wp-content/uploads/2013/08/map.png 500w, https://atlog.it/blog/wp-content/uploads/2013/08/map-300x200.png 300w" sizes="auto, (max-width: 450px) 100vw, 450px" /></a><figcaption id="caption-attachment-872" class="wp-caption-text">La galassia degli articoli su arXiv</figcaption></figure>
<p>Ma come è nato questo deposito di articoli (o <em>e-prints</em>) che, soprattutto in alcuni campi della fisica e della matematica, è ormai diventato un punto di riferimento imprescindibile? La storia ce la racconta nientemeno che il suo ideatore, il fisico teorico americano <a href="https://en.wikipedia.org/wiki/Paul_Ginsparg">Paul Ginsparg</a>, in <a href="http://arxiv.org/abs/1108.2700">questo articolo</a> (reperibile indovinate un po&#8217; dove?) di due anni fa.</p>
<p>Tutto comincia nella primavera del 1991, quando Ginsparg si trasferisce da Harvard ai <a href="http://en.wikipedia.org/wiki/Los_Alamos_National_Laboratory" target="_blank">laboratori di Los Alamos</a>, nel New Mexico, celebri per essere stati il luogo dove Fermi, Oppenheimer e gli altri membri del progetto Manhattan costruirono nel 1945 le prime bombe nucleari. Arrivato nel suo nuovo ufficio, Ginsparg scopre con piacere di avere a disposizione, per la prima volta in carriera, un computer tutto per lui (una <a href="http://en.wikipedia.org/wiki/NeXTstation" target="_blank">NeXTstation</a> a 25 MHz con hard disk da 105 Mb e 16 Mb di RAM) e ne approfitta per mettere in pratica un&#8217;idea che gli girava in testa da un po&#8217; di tempo.</p>
<p>Dobbiamo anzitutto precisare che all&#8217;epoca Internet non c&#8217;era ancora, o meglio stava nascendo proprio in quegli anni. La principale infrastruttura di rete, il cosiddetto <em>backbone</em>, era fornita dalla <a href="https://en.wikipedia.org/wiki/National_Science_Foundation_Network">NSFNet</a>, una rete creata nel 1985 per iniziativa della National Science Foundation che aveva raccolto il testimone dalla precedente <a href="https://en.wikipedia.org/wiki/ARPANET">ARPANET</a>. Nel 1991 la NSFNet collegava tra loro 13 nodi sparsi per gli Stati Uniti alla straordinaria (per i tempi) velocità di 1.5 Mbit/s:</p>
<p style="text-align:center;"><img loading="lazy" decoding="async" class="aligncenter" title="NSFNet" alt="Rete NSFNet nel 1991" src="https://upload.wikimedia.org/wikipedia/commons/a/ad/NSFNET-backbone-T1.png" width="450" height="331" /></p>
<p>Le più piccole reti regionali potevano poi mettersi in comunicazione tra di loro collegandosi al nodo NSFNet più vicino.</p>
<p>Questo primo abbozzo di rete globale fu fondamentale per facilitare i contatti tra gli accademici statunitensi e l&#8217;uso delle e-mail, prima limitato alle reti locali nelle singole università, divenne presto un&#8217;abitudine anche per le comunicazioni a lunga distanza. Tra l&#8217;altro, se diamo retta a Ginsparg, pare che sia stato proprio lui il primo ad avere l&#8217;idea di inserire tra i dati presenti nella testata dei propri articoli anche l&#8217;indirizzo e-mail, per la prima volta in <a href="http://www-public.slac.stanford.edu/sciDoc/docMeta.aspx?slacPubNumber=SLAC-PUB-4515">questo lavoro</a> del dicembre 1987:</p>
<figure id="attachment_876" aria-describedby="caption-attachment-876" style="width: 450px" class="wp-caption aligncenter"><a href="http://atlog.it/blog/wp-content/uploads/2013/08/copertina.png"><img loading="lazy" decoding="async" class="size-full wp-image-876" alt="Prima pagina del lavoro di Dixon, Ginsparg e Harvey" src="http://atlog.it/blog/wp-content/uploads/2013/08/copertina.png" width="450" height="332" srcset="https://atlog.it/blog/wp-content/uploads/2013/08/copertina.png 730w, https://atlog.it/blog/wp-content/uploads/2013/08/copertina-300x222.png 300w" sizes="auto, (max-width: 450px) 100vw, 450px" /></a><figcaption id="caption-attachment-876" class="wp-caption-text">&#8230;anche se relegato nelle note a pié di pagina</figcaption></figure>
<p>Un&#8217;altra cruciale innovazione di quegli anni fu la diffusione capillare del programma di typesetting <a href="http://en.wikipedia.org/wiki/TeX" target="_blank">TeX</a>, la cui versione &#8220;definitiva&#8221; era uscita due anni prima (1989). Molti ricercatori, soprattutto tra i più giovani, si erano convertiti rapidamente all&#8217;uso del nuovo sistema, soprattutto per via della notevole semplificazione che garantiva nella composizione delle formule matematiche.</p>
<p>Con la diffusione dei documenti elettronici i tempi erano maturi per pensare a una infrastruttura che facilitasse la diffusione rapida e su larga scala dei nuovi articoli non ancora arrivati alla pubblicazione su rivista (tipicamente perché in attesa di <a href="http://en.wikipedia.org/wiki/Peer_review" target="_blank">peer review</a>), i cosiddetti <em>preprint</em>. I primi tentativi in tal senso furono compiuti affidandosi a delle mailing list gestite manualmente, ma iscriversi a una mailing list di questo tipo significava correre costantemente il rischio di vedere la propria casella e-mail intasata dagli articoli in arrivo. Fu così che Ginsparg ebbe l&#8217;idea di creare un sistema completamente automatizzato che fosse in grado di ricevere ed archiviare i preprint, divulgare periodicamente una lista contenente i titoli e gli abstract dei preprint ricevuti, e infine distribuire gli articoli veri e propri su richiesta.</p>
<p>Nasce così la prima incarnazione del&#8217;arXiv, un rudimentale server e-mail (e, qualche mese dopo, anche FTP) gestito da un insieme di script <a href="https://en.wikipedia.org/wiki/C_shell">csh</a>, reperibile allo storico indirizzo <a href="http://xxx.lanl.gov/"><strong>xxx.lanl.gov</strong></a> (il curioso nome &#8220;xxx&#8221;, che ovviamente non ha nulla a che fare con la pornografia, deriva dalla sigla che Ginsparg era solito inserire nei suoi sorgenti TeX dove c&#8217;era qualcosa da correggere.) Il successo fu immediato: Ginsparg si aspettava un centinaio di preprint all&#8217;anno, ne arrivarono 400 nei primi sei mesi. L&#8217;onore della <a href="http://arxiv.org/abs/hep-th/9108001">prima</a> <em>submission</em>, ricevuta il 14 Agosto 1991, spettò al noto stringhista <a href="http://web.physics.ucsb.edu/~gary/">Gary Horowicz</a> assieme a J. H. Horne, mentre in <a href="http://arxiv.org/abs/hep-th/9108004">quarta posizione</a> (16 Agosto) troviamo nientemeno che <a href="https://en.wikipedia.org/wiki/Ed_Witten">Ed Witten</a>, peraltro non con uno dei suoi lavori più famosi, e <a href="http://arxiv.org/abs/hep-th/9108011">appena fuori dalla top ten</a> (21 Agosto) c&#8217;è il primo contributo di un altro grosso calibro, <a href="https://en.wikipedia.org/wiki/Ashoke_Sen">Ashoke Sen</a>.</p>
<p>Curiosamente, l&#8217;idea iniziale era di <em>cancellare</em> i preprint archiviati dopo tre mesi dalla loro ricezione, quando in teoria essi sarebbero stati resi obsoleti dalla pubblicazione su rivista dell&#8217;articolo corrispondente; ma <a href="http://en.wikipedia.org/wiki/Andrew_Strominger" target="_blank">Andrew Strominger</a> fece giustamente notare a Ginsparg che poter ottenere istantaneamente la copia di un articolo via e-mail è molto più comodo rispetto al perdere delle ore a cercare la relativa stampa nel proprio ufficio, e così nulla venne mai cancellato.</p>
<p>Ben presto cominciarono a spuntare &#8220;cloni&#8221; dell&#8217;archivio originale (ufficialmente denominato hep-th, che sta per <strong>h</strong>igh <strong>e</strong>nergy <strong>p</strong>hysics &#8211; <strong>th</strong>eory) relativi ad altre aree della fisica e della matematica: così il 5 Febbraio 1992 nasce l&#8217;archivio alg-geom (geometria algebrica) all&#8217;indirizzo eprints.math.duke.edu (oggi non più in uso), mentre l&#8217;8 Marzo arriva, a grande richiesta, l&#8217;archivio hep-ph (fenomenologia). Un poco più tardi, il 7 Aprile, nasce hep-lat (teorie su reticolo) e tre giorni più tardi arrivano astro-ph (astrofisica), cond-mat (fisica dello stato solido) e funct-an (analisi funzionale), questi ultimi ospitati in Italia, su un server della SISSA (<a href="http://babbage.sissa.it/">oggi, purtroppo, anch&#8217;esso defunto</a>).</p>
<p>Nell&#8217;autunno del 1992 Ginsparg viene a conoscenza di <a href="http://en.wikipedia.org/wiki/World_Wide_Web" target="_blank">una nuova e interessante tecnologia da poco sviluppata al CERN</a>, e decide di dare una mano alla libreria dello <a href="http://en.wikipedia.org/wiki/SLAC_National_Accelerator_Laboratory" target="_blank">SLAC</a> per mettere online un server web (il primo su suolo americano!) che consentisse, tra le altre cose, di accedere a un&#8217;altra storica risorsa che ogni fisico conosce ed ama, il database SPIRES (recentemente ribattezzato <a href="http://inspirehep.net/">inspire</a>). Un sito web per il &#8220;physics e-print archive&#8221;, com&#8217;era chiamato all&#8217;epoca, arriverà solo nell&#8217;Aprile del 1993.</p>
<p>Molti anni più tardi, e precisamente il 28 Dicembre del 1998, il sito acquisterà finalmente il nome <a href="http://arxiv.org">arXiv</a>, trasferendosi nel contempo al suo attuale indirizzo. L&#8217;idea che sta dietro a tale criptica sigla è che la X maiuscola va pensata come la lettera greca χ, da cui la pronuncia simile a quella della parola inglese «archive». Per la cronaca, il nome più ovvio di &#8220;archive&#8221; dovette essere scartato perché nel frattempo all&#8217;indirizzo <a href="https://archive.org/index.php">archive.org</a> si era già stabilmente insediato l&#8217;<a href="https://en.wikipedia.org/wiki/Internet_Archive">Internet Archive</a>: ecco un caso in cui persino l&#8217;essere nati prima ancora del web non è stato sufficiente ad assicurarsi il nome di dominio che si desidera!</p>
<blockquote><p>«The arXiv could well end up as string theorists&#8217; greatest contribution to science.» (<a href="http://en.wikipedia.org/wiki/David_Mermin" target="_blank">David Mermin</a>)</p></blockquote>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>De concisione</title>
		<link>https://atlog.it/blog/archives/749</link>
		
		<dc:creator><![CDATA[alberto]]></dc:creator>
		<pubDate>Sun, 28 Oct 2012 15:05:27 +0000</pubDate>
				<category><![CDATA[informatica]]></category>
		<guid isPermaLink="false">http://timeisntonmyside.wordpress.com/?p=749</guid>

					<description><![CDATA[Come sapete, <a title="Cambi di paradigma" href="../archives/187">da un po&#8217; di tempo a questa parte</a> ho eletto il Lisp, e più precisamente il suo dialetto Scheme, a mio linguaggio di programmazione preferito (in attesa di trovare il tempo di imparare lo <a href="http://en.wikipedia.org/wiki/Haskell_%28programming_language%29" target="_blank">Haskell</a> ). Una delle cose che più mi piace di Scheme è la sua grande concisione rispetto a linguaggi di programmazione &#8220;tradizionali&#8221; come il C e i suoi &#8230; ]]></description>
										<content:encoded><![CDATA[<p>Come sapete, <a title="Cambi di paradigma" href="../archives/187">da un po&#8217; di tempo a questa parte</a> ho eletto il Lisp, e più precisamente il suo dialetto Scheme, a mio linguaggio di programmazione preferito (in attesa di trovare il tempo di imparare lo <a href="http://en.wikipedia.org/wiki/Haskell_%28programming_language%29" target="_blank">Haskell</a>). Una delle cose che più mi piace di Scheme è la sua grande concisione rispetto a linguaggi di programmazione &#8220;tradizionali&#8221; come il C e i suoi derivati. Basti pensare alla quantità di codice che è necessario scrivere per implementare una funzione polimorfa in Scheme (dove è essenzialmente banale) e, ad esempio, in C++ usando i <a href="http://en.wikipedia.org/wiki/Template_%28C%2B%2B%29" target="_blank">template</a> e tutto il resto. Personalmente, trovo che la concisione sia una qualità molto importante: più la sintassi di un linguaggio è semplice, più i programmi scritti in quel linguaggio rispecchiano la struttura dell&#8217;algoritmo astratto che essi realizzano. Viceversa un linguaggio troppo verboso tende a nascondere le idee fondamentali in un sottofondo di codice inutile. Non bisogna però cadere nell&#8217;eccesso opposto, ovvero nella tentazione di rendere un linguaggio &#8220;il più conciso possibile&#8221;, il che può compromettere un&#8217;altra qualità molto importante: la facilità di lettura del codice.</p>
<p>Queste riflessioni sono ispirate da un vecchio <a href="http://www.rfc1149.net/blog/2006/02/08/the-j-programming-language/" target="_blank">articolo</a> in cui mi sono imbattuto recentemente che riguarda il <a href="http://en.wikipedia.org/wiki/J_%28programming_language%29" target="_blank">linguaggio di programmazione J</a>, ideato negli anni &#8217;90 da Ken Iverson come successore della sua precedente creazione <a href="http://en.wikipedia.org/wiki/APL_%28programming_language%29" target="_blank">APL</a>. Si tratta di un linguaggio molto diverso da quelli mainstream, sotto molti punti di vista. In particolare, la sua peculiare sintassi permette di scrivere programmi <strong>molto</strong> più concisi rispetto al loro equivalente in un linguaggio convenzionale. Ma la domanda è: ne vale la pena? Prendiamo ad esempio il codice illustrato nell&#8217;articolo di cui sopra:</p>
<pre class="brush: plain; title: ; notranslate">
+/1e6&lt;,!/~&gt;:i.100
</pre>
<p>Anche se a prima vista è difficile crederlo, questa stringa di 17 caratteri è un programma completo in J; esso calcola il numero di <a href="http://en.wikipedia.org/wiki/Binomial_coefficient" target="_blank">coefficienti binomiali</a> \(n\choose k\) maggiori di un milione, per \(n\) e \(k\) che variano da 1 a 100. Rimando all&#8217;articolo sopra citato per una spiegazione dell&#8217;algoritmo utilizzato.</p>
<p>La cosa interessante è che la stessa identica strategia risolutiva (sostituendo gli array con le liste) può essere implementata in Scheme, perdendo un po&#8217; in concisione ma guadagnando enormemente in trasparenza del codice. Proviamo a fare questo esercizio di traduzione, seguendo l&#8217;algoritmo così come spiegato dal buon Tardieu.</p>
<p>Anzitutto dobbiamo generare una lista dei primi 100 numeri naturali. Non casualmente, nella libreria <a href="http://srfi.schemers.org/srfi-1/srfi-1.html" target="_blank">srfi-1</a> c&#8217;è una funzione <code>iota</code> che è l&#8217;esatta traduzione dell&#8217;operatore <code>i</code> di J (e di APL). Quindi la nostra prima mossa sarà</p>
<pre class="brush: plain; title: ; notranslate">
(iota 100)
</pre>
<p>Proprio come in J, questo genera in realtà la lista dei numeri da 0 a 99, quindi occorre incrementare ciascun numero di una unità:</p>
<pre class="brush: plain; title: ; notranslate">
(map 1+ (iota 100))
</pre>
<p>Qui ho usato la procedura <code>1+</code> predefinita del mit-scheme, ma in qualunque altro interprete Scheme basterebbe usare la procedura anonima <code>(lambda (x) (+ x 1))</code>.</p>
<p>Supponiamo di avere già a disposizione una procedura <code>(binom n k)</code> che calcola il coefficiente binomiale di \(n\) e \(k\); dobbiamo costruire una tabella formata dai risultati di questa procedura per \(n\) e \(k\) che assumono ciascuno dei valori contenuti nella lista creata precedentemente. La soluzione di questo problema si ottiene, come ben sa chiunque abbia letto il secondo capitolo di <a href="http://mitpress.mit.edu/sicp/" target="_blank">SICP</a>, annidando due applicazioni di <code>map</code>. Il fatto che dobbiamo utilizzare lo stesso argomento per due volte significa che il problema ci sta supplicando di introdurre una procedura apposita, e noi lo accontentiamo:</p>
<pre class="brush: plain; title: ; notranslate">
(define (table f x)
  (map (lambda (n)
         (map (lambda (k)
                (f n k))
              x))
       x))
</pre>
<p>Questa procedura ritorna una lista di liste (la versione Lispiana di una matrice), ma noi vogliamo dimenticarci della suddivisione in righe e ottenere semplicemente una lista con tutti i coefficienti binomiali che abbiamo calcolato; vogliamo cioè &#8220;schiacciare&#8221; la nostra lista di liste, il che si fa usando <code>reduce</code> con <code>append</code>:</p>
<pre class="brush: plain; title: ; notranslate">
(reduce append
        '()
        (table binom (map 1+ (iota 100))))))
</pre>
<p>Dunque questo codice genera una lista con tutti i coefficienti binomiali desiderati. Per concludere occorre sostituire ciascuno di questi numeri con 1 o con 0 a seconda che esso sia maggiore di un milione o meno:</p>
<pre class="brush: plain; title: ; notranslate">
(map (lambda (n) (if (&gt; n 1000000) 1 0))
     (reduce append
             '()
             (table binom (map 1+ (iota 100))))))
</pre>
<p>e infine sommare tutti i risultati, ancora con <code>reduce</code>:</p>
<pre class="brush: plain; title: ; notranslate">
(reduce +
        0
        (map (lambda (n) (if (&gt; n 1000000) 1 0))
             (reduce append
                     '()
                     (table binom (map 1+ (iota 100))))))
</pre>
<p>(In realtà, da un punto di vista Lispiano sarebbe probabilmente più naturale usare <code>filter</code> per eliminare dalla lista tutti i numeri minori di un milione e ritornare come risultato la lunghezza della lista risultante; ma qui stiamo semplicemente facendo un esercizio di traduzione letterale, e quindi ci dobbiamo attenere all&#8217;algoritmo originario che è pensato per operare su array di lunghezza fissa piuttosto che su liste di lunghezza variabile.)</p>
<p>La prova del fuoco:</p>
<p><a href="http://atlog.it/blog/wp-content/uploads/2012/10/risultato.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-758" title="...ovvero il risultato" src="http://atlog.it/blog/wp-content/uploads/2012/10/risultato.png" alt="4075" width="450" height="125" srcset="https://atlog.it/blog/wp-content/uploads/2012/10/risultato.png 604w, https://atlog.it/blog/wp-content/uploads/2012/10/risultato-300x83.png 300w" sizes="auto, (max-width: 450px) 100vw, 450px" /></a></p>
<p>che è il risultato corretto.</p>
<p>Il bello è che i due programmi, l&#8217;originale in J e la sua traduzione in Scheme, si possono praticamente mettere in corrispondenza biunivoca:</p>
<p><a href="http://atlog.it/blog/wp-content/uploads/2012/10/corrisp.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-759" title="Corrispondenza" src="http://atlog.it/blog/wp-content/uploads/2012/10/corrisp.png" alt="" width="450" height="132" srcset="https://atlog.it/blog/wp-content/uploads/2012/10/corrisp.png 542w, https://atlog.it/blog/wp-content/uploads/2012/10/corrisp-300x89.png 300w" sizes="auto, (max-width: 450px) 100vw, 450px" /></a></p>
<p>Mi sembra inutile evidenziare quale delle due versioni sia maggiormente leggibile. Forse non è un caso se J e APL sono stati definiti, ironicamente ma fino a un certo punto, <a href="http://en.wikipedia.org/wiki/Write-only_language" target="_blank">linguaggi di sola scrittura</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>In memoriam: D.R., 1941-2011</title>
		<link>https://atlog.it/blog/archives/583</link>
					<comments>https://atlog.it/blog/archives/583#comments</comments>
		
		<dc:creator><![CDATA[alberto]]></dc:creator>
		<pubDate>Thu, 13 Oct 2011 22:35:46 +0000</pubDate>
				<category><![CDATA[amarcord]]></category>
		<category><![CDATA[informatica]]></category>
		<guid isPermaLink="false">http://timeisntonmyside.wordpress.com/?p=583</guid>

					<description><![CDATA[#include &#38;lt;stdio.h&#38;gt; main() { printf(&#38;quot;goodbye, worldn&#38;quot;); } Non ricordo di preciso a quando risale il mio primo incontro col <a href="http://en.wikipedia.org/wiki/The_C_Programming_Language" target="_blank">K&#38;R</a> . Mio fratello era probabilmente al secondo anno di università (al primo si studiava il <a href="http://en.wikipedia.org/wiki/Modula-2" target="_blank">Modula-2</a> ), quindi io avrò avuto tra i 12 e i 13 anni. Ho ancora bene in mente però l&#8217;impressione di curiosità &#8230; ]]></description>
										<content:encoded><![CDATA[<pre class="brush: cpp; light: true; title: ; notranslate">
#include &amp;lt;stdio.h&amp;gt;

main()

{
    printf(&amp;quot;goodbye, worldn&amp;quot;);
}
</pre>
<p>Non ricordo di preciso a quando risale il mio primo incontro col <a href="http://en.wikipedia.org/wiki/The_C_Programming_Language" target="_blank">K&amp;R</a>. Mio fratello era probabilmente al secondo anno di università (al primo si studiava il <a href="http://en.wikipedia.org/wiki/Modula-2" target="_blank">Modula-2</a>), quindi io avrò avuto tra i 12 e i 13 anni. Ho ancora bene in mente però l&#8217;impressione di curiosità che quel libro, con la sua buffa copertina bianca sulla quale campeggiava una grande C azzurra, aveva destato rapidamente in me una volta entrato in casa.</p>
<p>Un&#8217;altra cosa che ricordo bene è che quando iniziai a leggerlo, partendo diligentemente dalla prefazione (abitudine questa che mi è rimasta ancora oggi, per ogni tipo di libro), ci fu un passaggio che mi colpì in modo particolare. Siccome in questo momento non ho sottomano (e non posso reperire in alcun modo) una copia dell&#8217;edizione italiana, non posso fare altro che citarvi il paragrafo corrispondente dell&#8217;edizione originale:</p>
<blockquote><p>In our experience, C has proven to be a pleasant, expressive, and versatile language for a wide variety of programs. It is easy to learn, and it wears well as one&#8217;s experience with it grows. We hope that this book will help you to use it well.</p></blockquote>
<p>Ricordo che commentai la cosa con mio fratello, facendogli notare che a giudicare da questa descrizione il C sembrava una figata incredibile. Mio fratello (che non aveva letto la prefazione: per lui quello era un libro da studiare, non da leggere per diletto!) diede un&#8217;occhiata a quel passaggio e commentò: «Secondo me ci stanno prendendo per il culo».</p>
<p>In effetti non so se imparare il C da quel libro sia davvero un&#8217;esperienza &#8220;facile&#8221; o &#8220;piacevole&#8221; come la descrivono K&amp;R, però so che a quel libro, e di conseguenza ai suoi due autori, sono rimasto un po&#8217; affezionato, anche adesso che il C non lo uso quasi più. E così, quando oggi ho appreso della morte di <a href="http://en.wikipedia.org/wiki/Dennis_Ritchie" target="_blank">Dennis Ritchie</a>, il rubinetto della mia memoria ha perso un po&#8217;; e invece di lasciarli scorrere via, ho pensato bene di raccogliere i pochi ricordi che ne sono usciti in questo post. Dopotutto i blog dovrebbero servire anche a questo&#8230; almeno credo.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://atlog.it/blog/archives/583/feed</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Soluzione del quiz e commenti</title>
		<link>https://atlog.it/blog/archives/485</link>
					<comments>https://atlog.it/blog/archives/485#comments</comments>
		
		<dc:creator><![CDATA[alberto]]></dc:creator>
		<pubDate>Fri, 22 Jul 2011 14:17:24 +0000</pubDate>
				<category><![CDATA[informatica]]></category>
		<guid isPermaLink="false">http://timeisntonmyside.wordpress.com/?p=485</guid>

					<description><![CDATA[Siccome ogni promessa è debito, andiamo finalmente a spiegare in che modo ho generato l&#8217;immagine oggetto del <a href="../archives/476">quiz che vi ho proposto qualche giorno fa</a> . Anzi, già che ci siamo, eccone un&#8217;altra versione nuova di pacca, e ancora più dettagliata rispetto alla precedente: <a href="http://atlog.it/blog/wp-content/uploads/2011/07/new.png"></a> Si tratta di un classico esempio di <a href="http://it.wikipedia.org/wiki/Grafica_raster">immagine raster</a> , curioso termine che ha origine nella lingua inglese (in cui deriva &#8230; ]]></description>
										<content:encoded><![CDATA[<p>Siccome ogni promessa è debito, andiamo finalmente a spiegare in che modo ho generato l&#8217;immagine oggetto del <a href="../archives/476">quiz che vi ho proposto qualche giorno fa</a>. Anzi, già che ci siamo, eccone un&#8217;altra versione nuova di pacca, e ancora più dettagliata rispetto alla precedente:</p>
<p style="text-align: center;"><a href="http://atlog.it/blog/wp-content/uploads/2011/07/new.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-489" title="Grafico della relazione di divisibilità tra numeri naturali minori di 512" src="http://atlog.it/blog/wp-content/uploads/2011/07/new.png" alt="" width="512" height="512" srcset="https://atlog.it/blog/wp-content/uploads/2011/07/new.png 512w, https://atlog.it/blog/wp-content/uploads/2011/07/new-150x150.png 150w, https://atlog.it/blog/wp-content/uploads/2011/07/new-300x300.png 300w" sizes="auto, (max-width: 512px) 100vw, 512px" /></a></p>
<p>Si tratta di un classico esempio di <a href="http://it.wikipedia.org/wiki/Grafica_raster">immagine raster</a>, curioso termine che ha origine nella lingua inglese (in cui deriva dal latino <em>rastrum</em>, &#8220;rastrello&#8221;) ed è stato successivamente reimportato in italiano con il suo nuovo significato tecnico, in una sorta di girotondo linguistico. Un&#8217;immagine raster non è altro che una griglia rettangolare di pixel a ciascuno dei quali è associato un colore; nel nostro caso i colori in gioco sono solo due, bianco e nero, e si parla perciò più propriamente di una <em>bitmap</em>, o griglia di bit, l&#8217;idea essendo ovviamente che un bit acceso corrisponda a un pixel nero e un bit spento a uno bianco (o viceversa, non è importante).</p>
<p>Un&#8217;immagine di questo tipo si presta molto facilmente a rappresentare una relazione binaria tra numeri naturali: quest&#8217;ultima infatti non è altro che un insieme di <em>coppie ordinate</em> di elementi di \(\mathbb{N}\), o se si preferisce un sottoinsieme del prodotto cartesiano \(\mathbb{N}\times \mathbb{N}\) (che per definizione è l&#8217;insieme di <em>tutte</em> le coppie ordinate di numeri naturali). Ora, si dà il caso che \(\mathbb{N}\times \mathbb{N}\) sia proprio una griglia bidimensionale (infinita, ma non sottilizziamo&#8230;), e quindi che un suo sottoinsieme \(R\) sia completamente determinato &#8220;accendendo&#8221; tutti e soli i pixel di questa griglia che corrispondono a coppie \((a,b)\) di numeri naturali che appartengono a \(R\). Si ottiene così quello che si suole chiamare il <strong>grafico</strong> della relazione binaria \(R\).</p>
<p>Nell&#8217;immagine precedente la relazione raffigurata è quella di <em>divisibilità</em>, usualmente denotata \(a\mid b\), definita come segue:</p>
<p style="text-align: center;">\(a\mid b\) se e solo se esiste \(n\in \mathbb{N}\) tale che \(b = na\)</p>
<p>In altri termini, il pixel di coordinate \((a,b)\) (partendo dall&#8217;angolo in alto a sinistra) è acceso se e solo se \(a\mid b\), cioè \(a\) divide \(b\).</p>
<p>Naturalmente il discorso può essere ripetuto pari pari per qualunque altra relazione tra numeri naturali. Ad esempio, due numeri \(a\) e \(b\) si dicono <em>coprimi</em> se non hanno fattori primi in comune, o equivalentemente se il loro m.c.d. è 1. Il seguente è il grafico della relazione &#8220;\(a\) è coprimo a \(b\)&#8221; sull&#8217;insieme dei numeri naturali minori di 80, ingrandito quattro volte (o se preferite, con pixel di lato 4):</p>
<p><a href="http://atlog.it/blog/wp-content/uploads/2011/07/coprime-scaled.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-499" title="Grafico della relazione di coprimalità" src="http://atlog.it/blog/wp-content/uploads/2011/07/coprime-scaled.png" alt="" width="450" height="450" srcset="https://atlog.it/blog/wp-content/uploads/2011/07/coprime-scaled.png 512w, https://atlog.it/blog/wp-content/uploads/2011/07/coprime-scaled-150x150.png 150w, https://atlog.it/blog/wp-content/uploads/2011/07/coprime-scaled-300x300.png 300w" sizes="auto, (max-width: 450px) 100vw, 450px" /></a></p>
<p>Niente male, nevvero? La vedrei bene come stampa da appendere al muro, o magari come tappeto, al posto di un più classico persiano.</p>
<p>Tra l&#8217;altro, certe proprietà di una relazione binaria emergono chiaramente dal suo grafico: ad esempio l&#8217;immagine precedente è simmetrica per riflessione attorno alla diagonale principale, il che corrisponde al fatto che la relazione di coprimalità è <em>simmetrica</em> (se \(a\) è coprimo con \(b\) allora è anche vero che \(b\) è coprimo con \(a\)). O ancora, la diagonale principale è formata da soli pixel bianchi: questo significa che la relazione in esame è <em>irriflessiva</em> (nessun numero è coprimo con sé stesso). Viceversa nell&#8217;immagine a inizio post la diagonale principale è formata da soli pixel neri: questo perché ogni numero è divisibile per sé stesso, ovvero la relazione di divisibilità è <em>riflessiva</em>. Per la cronaca, essa è anche antisimmetrica e transitiva (e quindi è una relazione d&#8217;ordine parziale), e con un po&#8217; di impegno anche queste altre proprietà potrebbero essere messe in evidenza per via grafica.</p>
<p>Ma parlare di queste cose ci porterebbe su un&#8217;altra strada; quello che voglio fare adesso è invece spiegare in che maniera ho generato queste immagini. Si tratta in realtà di un esercizio di programmazione abbastanza semplice. Come i lettori di vecchia data di questo blog forse ricorderanno, <a href="../archives/187">da circa un anno a questa parte</a> il mio linguaggio di programmazione preferito è il Lisp, nella sua variante nota come <a href="http://en.wikipedia.org/wiki/Scheme_%28programming_language%29">Scheme</a>, ed è pertanto in tale linguaggio che ho implementato il programma in questione.</p>
<p>Ora, poiché il Lisp è sfortunatamente molto poco conosciuto rispetto a linguaggi più tradizionali come C e derivati, immagino che questo post perderà gran parte del suo interesse per molti di voi. D&#8217;altro canto non posso neanche somministrarvi un <em>crash-course</em> del tipo &#8220;il Lisp in mezz&#8217;ora&#8221; (ammesso che una cosa del genere sia possibile), quindi non mi resta che confidare nella leggibilità del mio codice. Almeno una cosa però la devo assolutamente spiegare: laddove nella stragrande maggioranza dei linguaggi di programmazione si scrive <code>f(x)</code> per indicare l&#8217;applicazione della funzione <code>f</code> all&#8217;argomento <code>x</code>, in Scheme si scrive invece <code>(f x)</code>; similmente si scrive <code>(f a b)</code> se <code>f</code> è una funzione di due argomenti, e così via. La stessa notazione si applica anche ai predicati: così ad esempio un test quale <code>a&gt;0</code> si scrive (in maniera un po&#8217; perversa) come <code>(&gt; a 0)</code>. Senza questa dritta, un sorgente Lisp rischia di sembrare solo un&#8217;accozzaglia di parentesi messe giù a caso.</p>
<p>Il modo più naturale di implementare in Scheme una relazione binaria tra numeri naturali è quello di definire il corrispondente <em>predicato</em>, cioè una procedura che mangia due numeri naturali e ritorna <code>#t</code> (&#8220;vero&#8221;) se i due numeri sono in relazione tra loro e <code>#f</code> (&#8220;falso&#8221;) altrimenti. Ad esempio per la relazione di divisibilità questo si fa come segue:</p>
<pre class="brush: plain; title: ; notranslate">
(define (divides? a b)
  (if (= a 0)
      (= b 0)
      (= (remainder b a) 0)))
</pre>
<p>(È convenzione comune in Scheme dare ai predicati un nome che termina con un punto di domanda, per evidenziare che il risultato è un valore di verità. La sintassi dell&#8217;espressione condizionale <code>if</code> è quella che ci si aspetta: <code>(if x y z)</code> significa &#8220;se <code>x</code> è vero allora il risultato è <code>y</code>, altrimenti è <code>z</code>&#8220;.)</p>
<p>In generale, supponiamo di avere un predicato <code>pred</code> cui si possa dare in pasto una qualunque coppia di numeri naturali e di voler produrre il suo grafico. Siccome i numeri naturali sono infiniti (ma va?), dovremo accontentarci di graficare la relazione su un sottoinsieme di \(\mathbb{N}\times \mathbb{N}\), per esempio sul quadrato \([0,n]\times [0,n]\). La prima cosa da fare è quella di calcolare <code>(pred a b)</code> per tutti i valori di <code>a</code> e <code>b</code> compresi tra 0 e \(n\) e memorizzare i risultati in una struttura dati opportuna. Siccome in Lisp (che, ricordiamo, è l&#8217;acronimo di <strong>lis</strong>t <strong>p</strong>rocessing) la struttura dati per eccellenza è la lista, raccoglieremo tutti questi simpatici bit in una lista. Questo si può fare con una ricorsione che, se stessi scrivendo in inglese, definirei <em>almost straightforward</em> (è un classico esercizio da primi capitoli di un libro di programmazione in Lisp), e otteniamo così una procedura di questo tipo (in cui supponiamo che i simboli <code>pred</code> e <code>n</code> siano già definiti):</p>
<pre class="brush: plain; title: ; notranslate">
(define (gen-bit-list i j)
  (cond ((&gt; i n) '())
        ((= j n) (cons (pred i j)
                       (gen-bit-list (+ i 1) 0)))
        (else (cons (pred i j)
                    (gen-bit-list i (+ j 1))))))
</pre>
<p>(<code>cond</code> è un costrutto analogo allo <code>switch</code> del C: si tratta di un condizionale multiplo, o sequenza di <code>if</code> effettuati uno dopo l&#8217;altro.) L&#8217;indice <code>i</code> corre sulle righe e l&#8217;indice <code>j</code> sulle colonne, e la ricorsione è sul quadrato \([0,n]\times [0,n]\) con l&#8217;ordinamento lessicografico. Questo significa che l&#8217;indice <code>j</code> viene incrementato fino a raggiungere la fine di una riga (<code>j=n</code>); quando ciò accade viene incrementato <code>i</code> e resettato a zero <code>j</code>. La condizione di terminazione è <code>i&gt;n</code>, nel qual caso la procedura ritorna la lista vuota (che in Scheme si denota con <code>'()</code> e in altri dialetti di Lisp con <code>nil</code>); la ricorsione fa il resto, costruendo a partire da questo caso base la lista desiderata.</p>
<p>C&#8217;è ancora un piccolo <em>caveat</em>: siccome un predicato ritorna non un numero ma un valore di verità (cioè <code>#t</code> o <code>#f</code>), la procedura così com&#8217;è costruisce in realtà una lista di valori di verità, mentre noi vogliamo una lista di bit. Per rimediare a ciò basta definire quello che in gergo si chiama un <em>wrapper</em>, cioè una procedura che &#8220;avvolge&#8221; il predicato <code>pred</code> e converte il suo valore nella forma che desideriamo:</p>
<pre class="brush: plain; title: ; notranslate">
(define (pred-wrapper a b)
  (if (pred a b) 1 0))
</pre>
<p>e sostituire poi tutte le chiamate a <code>pred</code> con chiamate a <code>pred-wrapper</code>.</p>
<p>Occorre ora trasformare questa lista di bit in un&#8217;immagine bitmap vera e propria. Il modo più semplice per farlo è quello di usare il <a href="http://en.wikipedia.org/wiki/Netpbm_format" target="_blank" rel="noopener">formato (plain) PBM</a> che, per citare la relativa pagina di manuale, è talmente semplice che</p>
<blockquote><p>
we hardly need to define the format here, because you can decode it by inspection.
</p></blockquote>
<p>Sostanzialmente, un file plain PBM è formato da un header (che specifica larghezza e altezza della griglia di bit) seguito dalla sequenza di bit che compongono l&#8217;immagine, ciascuno dei quali è rappresentato dal numero 0 (bianco) o 1 (nero), separati da spazi. Più semplice di così si muore! Ecco la procedura che scrive la lista di bit ottenuta in precedenza nel file associato alla porta <code>port</code> (che deve essere stata precedentemente aperta in scrittura):</p>
<pre class="brush: plain; title: ; notranslate">
(define (write-bit-list lst port)
  (if (null? lst)
      (display &quot;\n&quot; port)
      (begin (display (string (car lst) &quot; &quot;) port)
             (write-bit-list (cdr lst) port))))
</pre>
<p>(<code>car</code> e <code>cdr</code> sono i nomi che il Lisp dà alle procedure che ritornano la testa e la coda di una lista, quelle che di solito vengono chiamate <em>head</em> e <em>tail</em>.)</p>
<p>A questo punto resta solo da mettere assieme queste procedure con il codice che provvede ad aprire il file di output e a scrivere l&#8217;header PBM. Il programma completo è:</p>
<pre class="brush: plain; title: ; wrap-lines: false; notranslate">
(define (graph pred n filename)
  (define (pred-wrapper a b) (if (pred a b) 1 0))

  (define (gen-bit-list i j)
    (cond ((&gt; i n) '())
          ((= j n) (cons (pred-wrapper i j)
                         (gen-bit-list (+ i 1) 0)))
          (else (cons (pred-wrapper i j)
                      (gen-bit-list i (+ j 1))))))

  (define (write-bit-list lst port)
    (if (null? lst)
        (display &quot;\n&quot; port)
        (begin (display (string (car lst) &quot; &quot;) port)
               (write-bit-list (cdr lst) port))))

  (let ((outport (open-output-file filename)))
    (display (string &quot;P1\n&quot; (+ n 1) &quot; &quot; (+ n 1) &quot;\n&quot;)
             outport)                             ; PBM header
    (write-bit-list (gen-bit-list 0 0) outport)   ; raster data
    (close-output-port outport)))
</pre>
<p>L&#8217;immagine del quiz è stata prodotta con un comando del tipo<br />
<code>(graph divides? 255 "prova.pbm")</code> e successivamente sottoposta a un veloce passaggio con <a href="http://en.wikipedia.org/wiki/GIMP" target="_blank" rel="noopener">GIMP</a> per convertirla in formato PNM compresso e ingrandirla.</p>
<p>In realtà, questa prima versione di <code>graph</code> può essere migliorata in vari modi. Tanto per cominciare, notiamo che la lunghezza della lista di bit generata da <code>gen-bit-list</code> cresce come il quadrato di <code>n</code> (lato dell&#8217;immagine), e ciò può portare a ricorsioni che esauriscono lo spazio disponibile per lo stack anche per valori di <code>n</code> relativamente bassi. Un modo di procrastinare questo problema è quello di memorizzare, al posto dei singoli bit, direttamente i byte che si ottengono &#8220;impacchettando&#8221; 8 bit alla volta. In questo modo diventa anche molto più facile creare in output un file in formato PBM vero e proprio (che si differenzia dal plain PBM proprio per il fatto che i bit sono rappresentati come tali, cioè come cellette all&#8217;interno di un byte, e non tramite i simboli 0 e 1).</p>
<p>Un&#8217;altra piccola ma significativa modifica consiste nell&#8217;introdurre la possibilità di graficare la relazione data non necessariamente sul quadrato \([0,n]\times [0,n]\) ma su un qualunque rettangolo \([r_{0},r_{1}]\times [c_{0},c_{1}]\) per opportuni numeri naturali \(r_{0}\), \(r_{1}\), \(c_{0}\) e \(c_{1}\). Implementando tutte queste idee sono arrivato alla versione corrente del programma (ribattezzato <code>pred-plot</code>), con cui ho prodotto le immagini di questo post:</p>
<pre class="brush: plain; title: ; wrap-lines: false; notranslate">
(define (pred-plot pred r0 r1 c0 c1 filename)
  (define (pred-wrapper a b) (if (pred a b) 1 0))

  (define (pad w)
    (if (= (string-length w) 8)
        w
        (pad (string w 0))))

  (define (gen-byte-list i j w)
    (cond ((&gt; i r1)
           '())
          ((&gt; j c1)
           (cons (pad w) (gen-byte-list (+ i 1) c0 &quot;&quot;)))
          ((= (string-length w) 8)
           (cons w (gen-byte-list i j &quot;&quot;)))
          (else
           (gen-byte-list i (+ j 1) (string w (pred-wrapper i j))))))

  (define (write-byte-list lst port)
    (if (null? lst)
        (display &quot;\n&quot; port)
        (begin (write-char (integer-&gt;char (car lst)) port)
               (write-byte-list (cdr lst) port))))

  (let ((byte-list (map (lambda (w) (string-&gt;number w 2))
                        (gen-byte-list r0 c0 &quot;&quot;)))
        (outport (open-output-file filename)))
    (display (string &quot;P4\n&quot; (+ (- c1 c0) 1)
                     &quot; &quot; (+ (- r1 r0) 1) &quot;\n&quot;)
             outport)                             ; PBM header
    (write-byte-list byte-list outport)           ; raster data
    (close-output-port outport)))
</pre>
<p>(Nota: il codice precedente funziona senza problemi con l&#8217;<a href="http://www.gnu.org/software/mit-scheme/" target="_blank" rel="noopener">interprete Scheme del MIT</a>, che è quello che uso di solito; non garantisco per gli altri, anche se un qualunque interprete R5RS dovrebbe andare bene.)</p>
<p>L&#8217;ovvio passo successivo consiste nel passare dalle immagini in bianco e nero a quelle in toni di grigio, ovvero dal grafico di una <em>relazione</em> binaria a quello di una <em>operazione</em> binaria. Ciò rende possibile ad esempio generare immagini come questa:</p>
<p><a href="http://atlog.it/blog/wp-content/uploads/2011/07/plus.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-509" title="Addizione" src="http://atlog.it/blog/wp-content/uploads/2011/07/plus.png" alt="" width="256" height="256" srcset="https://atlog.it/blog/wp-content/uploads/2011/07/plus.png 256w, https://atlog.it/blog/wp-content/uploads/2011/07/plus-150x150.png 150w" sizes="auto, (max-width: 256px) 100vw, 256px" /></a></p>
<p>che rappresenta il grafico dell&#8217;addizione nel quadrato \([0,255]^{2}\). Per questo e altri sviluppi vi rimando però a una prossima (spero) puntata.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://atlog.it/blog/archives/485/feed</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
	</channel>
</rss>
