Friday 4 July 2014

C#-Emacs-hakkerointispeksi

Here is a spec for an emacs-hack I'm inclined to make. It's designed to ease the pain of developing C# on windows.I guess it will be mostly useful on cli- and library projects, but it might provide something useful for the winforms projects too. It however won't provide anything for the WPF-development, because I have no projects on it currently, and it's been ages since I've last used it. The text is in finnish, because it is more like a mind dump for myself to quickly restore the ideas to my head when I'll begin hacking than a real spec, and I can't be arsed to translate it. If I'll get any results however I'll write the code & docs in english.

Jos mulla ideaali csharp-ympäristö oisi, miltä se näyttäisi? Noh, Emacsilta tietysti.

Siinä olisi REPL

Eval()in on monta kertaa näytetty olevan toteutettavissa ihan C#;llä suoraan, tarvitsematta kirjoittaa mitään parseria, IL-generaattoria tai muuta pumhuukia. Tämä mahdollistaa alkeellisen C#-REPLin toteuttamisen Emacsiin. Roslynistä tai VS:n Immediate Windowsta voisi myös hakea hakkerointikelpoista pohjaa tai inspiraatiota.

Jos oikein dynaamisia haluttaisiin olla (, käytettäisiin ClojureCLRää tai muuta Lispiä :P), kerrottaisiin Emacsille csc.exen sijainti, ja tälle syötettäisiin kaikki metodimäärittelyt ja isommat, mitä repliin saadaan. Metodeista tulisi jotain Callable-semanttisia luokkia, ja luokista tulisi... noh, luokkia. Csc:llä näistä tehtäisiin .dll-asmeja, jotka ladataan repl-imageen Assembly.LoadAssemblyllä (tai jollain, msdn ei sattuneesta syystä ole bussissa matkaavalla cli-arch-pikkupäpällä käytettävissä). Systeemistä ei tulisi kaunis, replillä generoitujen luokkien käyttö saattaisi vaatia melkoista kikkailua sekä Emacsin että replserverin päässä, replissä määriteltyjen metodien ja luokkien scopelle olisi melkoisia rajoitteita, esimerkiksi luokkien perintä lie mahdotonta toteuttaa, koska perittäviä luokkia ei voi AFAIK käyttäjä ladata, ja rajapinnoista tulisi täysin turhia.

Toisaalta - jos metodiluokkien toteutukset piilottaa hashmappiin, ne olisivat ainakin REPL-expressionien tasolla olemassa. REPL-luokkamäärityksiin niitä tuskin saisi esiin ilman kikkailua. Perinnän voisi huijata niin, että Emacsissa parsii perintämäärittelyt, ja toteuttaa perittävästä luokasta olion uuden luokan kentäksi sekä toteuttaa method-missing - metodin (mikä on toteutettavissa C#:ssä, kuten muutaman viikon takainen googlailuni osoitti), joka delegoi kaikki perityt metodit tälle kentälle. Override-määreiset metodit eivät myöskään olisi paha toteuttaa - korvaa vain base-määreen _inheritedObj - määreellä. Suurin hassu on konstruktori, joka kutsuu base()a, mutta siitäkin selvinnee pienellä string-magialla ( :base(& params) muutetaan konstruktorin ensimmäisellä rivillä _inheritedObj = new _inheritedClass(& params);iksi.

Voisiko VS:n debuggerin kanssa keskustella? Tai ainakin pitää silmällä missäpäin projektia seikkaillaan, ja breakpointin tapahtuessa herättää Visual Studion UI:ssa oikea koodinpätkä esiin? Teoriassa breakpointit voisivat olla toteutettavissa Emacsin sessioon, josta ne lähetetään VS:lle/debuggerille, mutta käytännössä helpompi vain delegoida System.Diagnostics.Debugger.Break(); - kutsut jonnekin.

Toisaalta, jos debuggerin kanssa voi keskustella, repl-hässäkkään pitäisi saada näkyville breakpointin lexical scope. Tämä mahdollistaisi repl-hässäkän soveltamisen samoissa usecaseissa kuin VS:n Immediate Window. Lisäksi lambdat käsiteltäisiin oikein :)

Debuggerissa pitäisi komentaa myös C-d C-e - nappien mukaan, jos ei muuten niin ainakin BREAK ON ALL_CLR_EXCEPTIONs - booleanasetus

Mitäs muuta? Kaikki debuggerin ja debugattavan prosessin outputstreamit pitäisi saada kaapattua Emacsiin. Console on helppo, evaluoidaan Console.SetOut(outputsocket.GetStream), mutta Tracesta ja muista debuggivirroista en tiedä.

Tietysti moden pitäisi osata myös clean, build ja start koko sln:lle (vaikka start lie parempi toteuttaa restarttina, joka nollaa replin tilan). Jonkinlainen integraatio sourcesafeen ei olisi huono, winformsille pitäisi kehittää jonkinlainen ajatus, ja taikanappi, joka avaa auki olevan tiedoston Visual Studioon ennalta-arvaamattomien käyttötapausten varalta.

Miltä tällainen csharp-moodi kuulostaisi? En ole saanut hakkeroitua olemassaolevia moodeja toimimaan Emacsin kanssa, mutta tämä speksi kuulostaisi aika täydelliseltä ainakin cli-c#-projektihin, ja tuosta repl-serveristä voisi hakkeroida muitakin juttuja Windowsille ja Monolle. Tuskin hakkeroin tosin; Unixilla leiningenin käyttö sattuu paljon vähemmän aivoon, ja tämän moodin ajatus on vähentää tuskiani windowskehityksessä... Ehkä tätä voisi soveltaa Unityn kanssa?

Disclaimerina sanottakoon, että voin puhua aivan höpöjä tässä tekstissä: en tiedä juuri mitään parsereista ja muista kääntäjätekniikoista, ja minulla on vain pieni aavistus .NETin ja Emacsin toimintaperiaatteista, joten yllätyksiä on varmasti luvassa.

No comments:

Post a Comment