Newsgroup: it.comp.os.dibattiti
Titolo: Idee sparse per shell object-oriented

Dobbiamo definire che cosa una shell object-oriented deve essere in grado
di fare. Cerco di mettere per iscritto le proposte già fatte e un paio di
cose che mi sono venute in mente:
1) un comando è un'operazione o un metodo eseguito su uno o più oggetti
(la differenza tra operazioni e metodi è puramente sintattica: se uso un
operatore, ad esempio l'assegnamento in forma a = b, ho un'operazione; la
sintassi a/assign(b) sarebbe invece quella di un metodo).
2) L'importanza delle conversioni automatiche è cruciale, per cui per
ogni tipo deve essere possibile definire operatori di conversione di tipo
3) Chiedere l'ereditarietà è chiedere troppo. Se un tipo di file è un
sottotipo "logico" di un tipo base, non è detto che che la struttura
interna sia altrettanto simile, per cui il tipo base può forzare i tipi
derivati a ridefinire (overriding) i suoi metodi.
4) Supponiamo di voler schedulare un'operazione a una certa ora: il modo
più naturale...
Scheduler.add(07.00am,  {
			Blind_Guardian_-_Wait_for_an_Answer.mp3.play()
			})
Cosa succede? Un comando della shell può essere trattato come se fosse
esso stesso un oggetto. {} è l'operatore di quoting, serve ad astrarre
dalla semantica di un comando, che diventa un'innocua stringa di
caratteri, da far scattare al momento opportuno. Ovviamente esiste anche
l'operatore inverso, l'unquoting [].
Nota: per il quoting è preferibile {} a "", per semplificare il quoting
annidato.
Esempio di unquoting: voglio scrivere dei dati su un file temporaneo.
Nulla di più semplice.
String filename = FileSystem.newtmpfile()
[filename].write("dati")
il metodo newtmpfile() dell'oggetto built-in FileSystem restituisce la
stringa del nome del file temporaneo. L'operatore [] traduce la stringa
nell'espressione che essa rappresenta (in questo caso nell'oggetto file
che ha nome uguale alla stringa filename).
5) I metodi stessi sono considerati degli oggetti, quando non sono seguiti
dall'operatore (). Un modo elegante per definire un metodo...
# associa winamp al tipo Mp3Audio
Mp3Audio.play = { 
		lambda(String $1)
		winamp $1
		adbmal 
		} 
# associa xmms a un singolo file
Blind_Guardian_-_Nightfall.mp3.play =   { 
					lambda(String $1)
					xmms $1
					adbmal 
					}
(uso la sintassi "lambda(...) ... adbmal" per definire oggetti funzione)
Lo pseudocodice utilizzato è pieno di inesattezze, incongruenze e
ambiguità, ma in attesa di risolverle dovrebbe essere sufficiente a dare
un'idea...
Saluti.
-- 
\/               
wirix...@libero.it
          ICQ UIN: 3233084
/\ e l l o s s   (per rispondermi in privato, elimina il DEMONE)

 cose che mi sono venute in mente:
Sull'argomento mi è stato segnalato
www.beanshell.org
Dagli un'occhiata, potrebbe essere una valida base di partenza, dato che
consente gia di accedere al filesystem.
Si tratta di trovare una implementazione funzionante delle classi wrapper,
dato che alla fine di questo si tratterebbe...
Saluti!
Raffaele

 
www.beanshell.org
Ti ispira? A me sembra molto lontano dall'idea di shell object-oriented
che avevo...
Che ne pensate dell'idea di "shell higher-order" che ho proposto a
capo-thread nei punti 4 e 5?


 che avevo...
http://www.beanshell.org/manual/quickstart.html#Useful_BeanShell_Commands
Qui ci sono alcuni comandi che rimandano ad una shell classica, tipo
cat(), o cd() e dir()
Sarebbe una base perfetta per implementare una shell OO, dato che essendo
gia OO di per se, richiederebbe solo l'implementazione delle classi
wrapper, e la modifica del parser dei comandi.
Questo ovviamente per vederla in modo semplicistico, ma rimane imho
un'ottima base.
Raffaele

 Saluti.
Ciao
-- 
E-Mail: 
risi...@libero.it
Sito Web: 
risitano.altervista.org
Gruppo: 
it.groups.yahoo.com/group/decomunistizziamo-internet/
"Noi vogliamo glorificare la guerra - sola igiene del mondo
il militarismo, il patriottismo, il gesto distruttore del liberatori, 
le belle idee per cui si muore."   F.T. Marinetti

 un metodo smalltalk like..
Ecco, non conosco smalltalk, vedrò di farmi un po' di cultura.
Ho cercato di formalizzare un po' meglio ciò che intendo per shell
object-oriented higher-order.
OGGETTI
1) String - è il tipo built-in su cui non viene fatta praticamente
nessuna assunzione e su cui vengono fornite poche operazioni (ad esempio
il concatenamento); di solito viene utilizzato per le variabili 2) File -
è il tipo built-in da cui tutti i tipi di file specializzati derivano
3) Executable - è un tipo built-in derivato da File, a cui appartengono
eseguibili nativi, script e metodi
4) Altri tipi built-in, anche con metodi statici (es: FileSystem,
Scheduler, ...) per le funzionalità della shell.
SINTASSI:
L'unità di base dell'esecuzione è il COMANDO. Un comando è:
1) <oggetto Executable> <lista dei parametri> 
Applica la lista dei parametri specificati all'Executable specificato (di
qualunque tipo esso sia):
pippo.mp3:play		# nessun parametro
tesi.doc:print lpt1	# stampa tesi.doc su lpt1
dir			# dir è un oggetto Executable built-in
			# (analogo ai comandi built-in)
2) <oggetto l-valore> = <espressione>
Esegue l'assegnamento per copia. oggetto l-valore dev'essere un nome di
variabile o di oggetto, ma non un'espressione di altro tipo.
destination.txt = source.txt		# esegue la copia (anche se 
					# destination.txt non esiste 
					# ancora!!!)
Classes:MP3:play = {| winamp $this}	# assegna al metodo play dei 
					# file MP3 l'esecuzione del 
					# player winamp
[tesi.doc:print lpt1] = "stinga inutile"# errore: non è un l-valore
Poiché perfino le istruzioni if, for, while e goto possono essere viste
come particolari oggetti Executable, ho motivo di credere che questi siano
gli unici due costrutti realmente necessari nella shell (anche il
costrutto di assegnamento potrebbe essere simulato col costrutto
eseguibile, ma appesantirebbe eccessivamente la notazione).
ESPRESSIONI
1) Un oggetto (variabile, file o built-in) è un'espressione
2) Applicazioni di altre espressioni a operatori o metodi sono espressioni
PARENTESI
Le parentesi () raggruppano le espressioni esplicitando l'ordine di
valutazione.
Le parentesi {|} sono l'operatore di astrazione e generano oggetti
Executable. Come si utilizzano? La sintassi è:
{ <lista di parametri> | <lista di simboli> }
Le parentesi [] sono l'operatore di riduzione, applicano parametri a
oggetti Executable e restituiscono la stringa del loro output.
Se voglio generare un Executable "Somma" che stampa la somma degli input
(supponendo che esista un oggetto Eval built-in per l'esecuzione di
operazioni matematiche, nonché un oggetto Echo per la stampa a video):
Somma = { $a $b | Echo [Eval $a + $b] }
E' ammessa anche la notazione posizionale dei parametri:
Somma = {| Echo [Eval $1 + $2] }
(Le parentesi [] funzionano né più né meno come la command-substitution
in bash)
Saluti.
-- 
\/               
wirix...@libero.it
          ICQ UIN: 3233084
/\ e l l o s s   (per rispondermi in privato, elimina il DEMONE)
***      La macchina di Turing ha un baco nel programma      ***
***             e noi l'aggiusteremo con il C++!             ***

 Saluti.
C'he dci apro un progetto su Sourceforge? 
che ne dici di oosh (object oriented shell) oppure hosh (higher order
shell)...


 oriented shell) oppure hosh (higher order shell)...
Mi sa che gli acronimi sono già stati presi ;).


 Saluti.


 di fare.
Non ho le competenze per commentare la giustezza delle cose da te
proposte, ma vorrei dire una cosa.
1) Trattandosi di una shell interattiva, è di fondamentale importanza il
completamento automatico, con pop-up a-la visual studio, tanto che il suo
funzionamento IMO andrebbe specificato assieme al linguaggio, non lasciato
all'estro delle implementazioni.
2) A tale proposito, è naturale aspettarsi che, appena si scrive il
nome di un oggetto e si preme il punto (.), venga fuori la lista dei
metodi/attributi dell'oggetto.
Fin qui niente di strano. Ma un attimo: la stessa cosa si può dire in un
altro modo: 
Il "." permette di specificare un oggetto, e MOSTRA TUTTI I
VERBI CHE HANNO SENSO CON QUELL'OGGETTO.
A questo punto, a chi ha visto segusoLand, dovrebbero fischiare le
orecchie e squillare campanelli nella testa:
QUESTO SISTEMA NON PERMETTE DI SPECIFICARE _DUE_ oggetti, e mostrare solo
le cose che hanno senso con entrambi. 
Cosa che sarebbe _molto_ desiderabile in una shell interattiva: ad
esempio, io vorrei poter scrivere il nome della stampante e un nome di
file, e vedere nel completamento automatico solo il verbo stampa(file,
stampante), non il verbo cancella(file), che c'entra con i file ma con la
stampante non c'entra niente.
Insomma, attenzione ad usare il paradigma OO pari pari. Forse è meglio
fare tutto orientato a verbi, non ad oggetti, ed ideare una sintassi tipo
(file1 printer2).          //questi sono due oggetti tra parentesi seguiti
                           //dal punto
E appena digiti il punto, compaiono solo i metodi che hanno senso con
_entrambi_ gli oggetti:
stampa(FILE, PRINTER).
My two cents.
-- 
Best Regards,
Maurizio Colucci
Please remove the uppercase letters "S,P,A,M":
seSgPuAsM...@tin.it

 le cose che hanno senso con entrambi. 
Questa č da studiare, messa cosě non č che mi piaccia molto, anche se č
giusto e saggio prevedere l'iterazione tra piů oggetti. Il fatto č che il
metodo per esempio "print" prevede gia l'utilizzo della periferica
"stampante" come default, e opzionalmente altre periferiche, come
"altraStampante", "file", etc
Non so...
Raffaele

 "altraStampante", "file", etc


 file stampabili.
la comparsa dei file stampabili deve essere subordinato al metodo di
stampa:
oosh>printer1. [TAB]
print    configure
oosh>printer1.print. [TAB]
pippo.txt    pluto.doc    paperino.rtf
Dai, che pian piano mettiamo insieme qualcosa di sensato!
Raffaele
-- 
Raffaele Castagno
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 oosh>printer1.print. [TAB]
Vedi che ti stai contraddicendo? Prima sembra che print sia un metodo di
txt, poi di printer. Devi decidere.
La verità è che non va bene nessuna delle due soluzioni. Né va bene
duplicare il metodo, ovviamente. 
Esistono casi in cui io voglio scrivere stampante PUNTO e avere la lista
dei verbi. Esistono casi in cui voglio scrivere file PUNTO ed avere la
lista dei verbi. 
È una falla di base del paradigma oo. 
Ad esempio, in C++ non esiste un modo "giusto" di procedere:
  math.add(point, vector)
oppure
 vector.add(point)
oppure
  point.add(vector).
Tutte e tre le soluzioni sono artificiose.
L"unica soluzione a questo problema è che i verbi non devono essere
raggruppati dentro un solo oggetto


 raggruppati dentro un solo oggetto
Non capisco cosa intendi... i metodi (verbi non è un termine oo...) non
sono racchiusi in un solo oggetto. Ogni oggetto ha i suoi. printer1 ha il
SUO metodo print, mentre pippo.txt ha il SUO print, che hanno una funzione
idealmente simile, ma sostanzialmente differente.


 avere un significato diverso per un altro oggetto.
Hai due implementazioni che fanno la stessa cosa. io davo per scontato che
questo fosse non accettabile. Se per te va bene, non ho piů nulla da dire.
===
Riassumo: 
Io la vedo cosě: il metodo print(file, stampante) ha a che fare
sia con la classe file che con la classe stampante. Quindi č sbagliato,
concettualmente, metterlo sia nell'una che nell'altra classe.
Concretamente, qual č il problema? Ecco: se costringi i metodi ad
appartenere esclusivamente ad una classe (come fanno c++, java, C# ecc),
succede questo:
un programmatore pigro fa soltanto il metodo printer::print(file) e non fa
il metodo file::print(printer). L'utente scrive file1. e si aspetta di
vedere il popup di un metodo print(), che perň non appare. Questo non
deve poter succedere, IMHO.


 deve poter succedere, IMHO.
Questo è facilmente evitabile, in diversi modi. Per esempio definendo un
metodo print() di base ereditato da tutte le classi derivate, oppure
definendo delle classi astratte. Le classi astratte hanno solo la
definizione dei metodi, e il compilatore obbligherà lo sviluppatore ad
implementarli nelle classi derivate. Se un programmatore pigro o distratto
non implementa il metodo print della nuova classe di file che sta creando,
il compilatore lo insulterà malamente dicendogli che il metodo DEVE essere
implementato.
Ad ogni modo, prevedendo un core di base, si provvederà a dare un supporto
almeno di base sui vari tipi di file. Per farti un esempio, il metodo
print dei file sconosciuti potrebbe limitarsi a scrivere a video il nome
del file, o un messaggio del tipo "File sconisciuto, non è attualmente
disponibile alcun sistema di stampa".
Ovviamente il metodo print verrebbe interdetto nei casi in cui il file in
questione non ne abbia proprio bisogno.
Ciao


 implementato.
Ma non lo costringe a dare la stessa implementazione.
Ciao!


 Questo non deve poter succedere, IMHO.
Non e' detto che ci sia la classe file o la classe printer. Secondo me pero'
l'idea e' che la shell dovrebbe funzionare in entrambi i modi che hai detto,
perche' nessuno dei due e' per qualche motivo escludibile. Quindi si' a
shell OO, ma non e' detto che l'implementazione sottostante debba essere 1:1
con quella apparente.
Saluti.
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (
http://www.grisoft.com
).
Version: 6.0.560 / Virus Database: 352 - Release Date: 08/01/2004

 Ma non lo costringe a dare la stessa implementazione.
E non deve farlo. Come ti ho detto, file di tipo diverso possono
richiedere un diverso sistema di stampa.
Raffaele

 .xls
ho già risposto


 evento logico taglierebbe le mani agli sviluppatori...
IMHO non è possibile farlo senza perdere in generalità.
Inoltre uno potrebbe voler modificare il codice del metodo
stampante::stampa senza stravolgerne la semantica. L'ideale ovviamente
sarebbe rilevare le modifiche che confliggono con la semantica di
stampante::stampa e non consentirle, ma da programma non si può fare.


 >> ma non necessariamente con la stessa implementazione.
allora:
printer::print(String fileName)
{
 lpr fileName; //lpr è un programma di stampa presente sul sistema
}
txt::print()
{
 -printer.print(this.fileName); // '-' serve a forzare la chiamata al
metodo
}
pdf::print()
{
 -printer.printPdf(this.fileName); //pdf print è un programma di stampa
}
La definizione di txt::print() viene definita automaticamente al momento
di installare la shell con i valori di default, ovvero la chiamata al
metodo di stampa generico della stampante di default.
L'implementazione di pdf::print in questo caso è la chiamata ad un metodo
di printer, ma non necessariamente.
In ogni caso, se io chiamo:
printer.print(pdf)
la chiamata viene rimappata su:
pdf.print()
il fatto che in questo caso viene poi rimandata a :
printer.printPdf(pdf)
è solo un'esempio.
Per assurdo, nell'implementazione di pdf::print potrebbe esserci
printf("Ciao mondo")
Sarebbe perfettamente lecito, e daltronde anche impossibile da impedire.
Ancora, se l'utente non vuole usare il metodo di default, può forzare la
chiamata:
-printer:print(pdf)
che usando la definizione dell'esempio di prima cercherà di spedire
direttamente il pdf al programma lpr, che probabilmente insulterà in malo
modo l'utente...
Saluti
