Gå til innhold

søppel

Medlemmer
  • Innlegg

    838
  • Ble med

  • Besøkte siden sist

Innlegg skrevet av søppel

  1. http://en.wikipedia.org/wiki/Categorical_l...gical_languages

    Kan hende Prolog ikke er så dumt -- dette er "way over my head" egentlig.

     

    Kan man i det hele tatt være sikker på noe som helst hvis man "ikke gjør det selv", eller spesifiserer ting eksplisitt? (Til og med da skjer det ofte rare ting; fraktaler, C.A. og andre GameOfLife -lignende ting f.eks.)

     

    Edit:

    Til det andre du lurer på kan jeg vel sitere fra Paul Graham når han snakker om design og "Two-Phase Development":

    If programming were an entirely mechanical process - a matter of simply translating specifications into code - it would be reasonable to do everything in a single step. But programming is neven like that. No matter how precise the specificatios, programming always invelves a certain amount of exploration - usually a lot more than anyone had anticipated.

     

    It might seem that if the specifications were good, programming would simple be a matter of translatitng them into code. This is a widespread misconception. Programming necessarly invoves exploration, because specifications are necessarily vague. If they weren't vague, they wouldn't be specifications.

     

    (de ville vært kode i stedet altså) .. Jeg har i hvertfall ingen "design patterns" liggende i bakhodet enn de alt for generelle jeg allerede forsøkte å nevne (innser nå at jeg misforsto litt av oppgaven forresten). Så det blir vel til at du må utforske litt her - da jeg ikke vet åssen man skal angripe et slikt problem. Som du nevnte kan det kanskje være en idé å titte på andre biblioteker (eller kanskje spesifikasjonene/dokumentasjonen/"forskningspapirene" dems!), men jeg tror ikke C++ og Java er de aller, aller beste språkene til det her.

  2. Det er begrenset hvor mye erfaring jeg har med dette selv.

     

    Kan tenke seg at man har et sett med mulige funksjoner - og et sett med mulige data - og omtrent uendelige kombinasjoner av disse. Vi kan kalle én bestemt kombinasjon for DNA (en klasse f.eks.), et DNA består da av "pekere" til de mulige funksjoner (+, -, *, exp ..osv) og dataene (tilfeldige tall som f.eks. skal være parameter nr. 2 i sammenheng med parameter nr. 1 som er fra inndatarekken)...

     

    Så lager man (tilfeldige) instanser av et DNA og vi får en algoritme (objekt). Denne kjøres på settet med inndata og vi får ett sett utdata.

     

    Så må det være en rutine som sjekker om algoritmen er blandt de beste til nå.

     

    Så må den ha et sett med de 10 (f.eks.) beste algoritmene som får lov til å "formere" seg ved å bytte egenskaper seg i mellom (funksjonsvalg og data til variablene sine).

     

    I tillegg må det oppstå små (og noen ganger) større mutasjoner - dette vil si endringer av de egenskaper som er arvet fra "foreldre".

     

    Et programmeringsspråk som kan genere eller interprete kode @ runtime er lettest her tror jeg.

     

    Edit:

    (dette ble skrevet fryktelig raskt)

  3. Sjekk posten jeg refererte til i ang. kritikk av C/C++:

    http://forum.hardware.no/index.php?showtop...dpost&p=3391621

     

    Legg også merke til det zirener sier om forbedringer og endringer -- C++ er et språk i endring; det er en god ting - i flere sammenhenger. (se på Boost - og hvilke idéer de forsøker å implementere)

     

    Jeg er glad vi ikke sitter med hullkort fortsatt for å si det slik.

     

    Legg også merke til at jeg sa: "Jeg snakker ikke om C++ og standaren, men en idé."

     

    Edit:

    ..og alle endringer og ting relatert til kodeeksemplene mine blir selfølgelig halvveis - da jeg ikke kan endre selve kompileren og standaren på strak arm.

     

    Edit2:

    Og kan vi ikke snu på det nå - du ler altid av løsningene og idéene mine, jeg er nysjerrig på hvilke du har;

     

    Hvordan ville du implementert dette slik at koden til zirener fungerte:

    template<class T>                      
    T& operator=(T& lhs, const RefCount<T>& rhs)  
    {
    //lhs = rhs->p;
    //return lhs;
    }

    (i sammenhenger der T kan være innebyggde typer, ja)

     

    Ville du i det hele tatt implementert mulighet for dette?

    * Hvis ikke - hvorfor ikke?

    * Hvis - hvordan?

  4. Jupp, er redd du stort sett, eller som oftest, ikke kommer noen vei her.

     

    Nærmeste blir vel en disassembler.

     

    Det greieste er som regel å skaffe kildekoden til programmet (heh) - eller eventuellt bytte til et tilsvarende program der kildekoden er tilgjengelig (OpenSource og den mølja der .. :] ).

  5. saboi:

    Du misser totalt poenget - eller så vil du ikke se det fordi det kommer fra meg. Jeg kan ta et annet eksempel:

     

    Si jeg skal reise hjemmefra (Norge) til USA. Jeg vet det er mulig, fordi jeg har sett andre gjøre det - men ikke i detalj hvordan jeg kommer meg dit.

     

    Samme med programmeringsspråk - jeg vet det er mulig (andre språk), men ikke i detalj hvordan jeg kommer dit.

     

    Jeg greier i hvertfall ikke beskrive det med mer detaljer enn det jeg har gjodt hittil for deg. Spesiellt siden det er detjaler man prøver å unngå når man generaliserer (template-kode).

     

    På slutten her fokuserer du etterhvert på hva det på overflaten ser ut til at jeg gjør - når det som foregår i bakgrunnen (idéen bak kodeeksempler o.l., men det blir veldig spesifikt igjen) faller utenfor. Hvorfor du gjør dette forstår jeg ikke - for jeg tror du forstår hva som egentlig foregår her.

  6. Vekk med denne muligheten:

    struct X {
    X& operator=(const X& rhs);
    };

     

    ..og bare hatt denne:

    X& operator=(const X& lhs, const X& rhs);

     

    Da sitter du igjen med noe som tilsvarer assign-eksempelet ovenfor.

     

    Edit:

    Hvis jeg ikke misser noe - så er den første overflødig. private:-tingen er en liten detalj. (Lisp har valgt å fjerne private:-muligheten og heller legge den til på et lag uten på dette med klasser og sånn kallt packages).

  7. Jeg er ikke sikker på hva du mener, men går ut i fra at du mener "hvordan skal den velge hvilken funksjon den skal bruke av de overloadede"?

     

    #include <iostream>
    
    using namespace std;
    
    
    template<typename T>
    class RefCount {
    public:
    T& getIt()
    {
    return(_o);
    } // getIt
    
    private:
    T _o;
    }; // RefCount
    
    
    // Dette er operator= (og =), bare i en annen form (som gjør dette mulig i C++).
    // "den mer generelle"
    template<typename T>
    T& assign(T& a, T& b)
    {
    return(a = b); // = skulle ledet tilbake til mindre og mindre generelle funksjoner - til man havnet "på bunn"
    } // assign
    
    
    // Dette er operator= (og =), bare i en annen form (som gjør dette mulig i C++).
    // "den mer spesifike"
    template<typename T>
    T& assign(T& a, RefCount<T>& b)
    {
    return(a = b.getIt()); // = skulle ledet tilbake til mindre og mindre generelle funksjoner - til man havnet "på bunn"
    } // assign
    
    
    int main(int argc, char** argv)
    {
    RefCount<int> ri;
    ri.getIt() = 123;
    
    int i;
    // "den mer spesifike"
    assign(i, ri);
    cout << i << endl;
    
    int j;
    // "den mer generelle"
    assign(j, i);
    cout << j << endl;
    
    return(0);
    } // main
    

     

    Dette er en detalj som er uavhengig av syntaxen for meg -- man burde t.o.m. kunne skrive kode som spesifiserer hvordan kompileren gjør slike valg i forskjellige sammenhenger og tilfeller!

     

    Edit:

    template<typename T>
    T& assign(T& a, T& b) {
    if(T == SomeType) {
    // stuff here
    }
    
    if(T == SomeOtherType) {
    // other stuff here
    }
    }

     

    Virker sprøtt?

     

    Edit2: Oh, btw. .. jeg vet dette også er et dårlig eksempel - men selve eksempelet er ikke poenget.

  8. Slik den gjør her:

    // Dette er operator=, bare i en annen form (som gjør dette mulig i C++).
    template<typename T>
    T& assign(T& a, RefCount<T>& b)
    {
    return(a = b.getIt()); // = skulle ledet tilbake til mindre og mindre generelle funksjoner - til man havnet "på bunn"
    } // assign
    

     

    Tenk deg at = og operator= ikke eksisterer, men er erstattet av en funksjon assign og at det er den jeg overloader.

  9. en default operator= for T som blir laget automatisk, en som forfattern kanskje har skrevet selv for T eller din funksjon?

     

    Det burde kun eksistere én =, og den burde kunne overlastes manuellt av brukeren i forskjellige grader av generalitet. Jeg vil ikke tenke på, eller spesifisere (selv ja) slike detaljer før høyst nødvendig.

     

    #include <iostream>
    
    using namespace std;
    
    
    template<typename T>
    class RefCount {
    public:
    T& getIt()
    {
     return(_o);
    } // getIt
    
    private:
    T _o;
    }; // RefCount
    
    
    
    // Dette er operator=, bare i en annen form (som gjør dette mulig i C++).
    template<typename T>
    T& assign(T& a, RefCount<T>& b)
    {
    return(a = b.getIt());	// = skulle ledet tilbake til mindre og mindre generelle funksjoner - til man havnet "på bunn"
    } // assign
    
    
    int main(int argc, char** argv)
    {
    RefCount<int> ri;
    ri.getIt() = 123;
    
    int i;
    assign(i, ri);
    cout << i << endl;
    
    return(0);
    }	// main
    

     

    Jeg vet det andre eksempelet er idiotisk - det understreker poenget mitt; det burde vært lovelig sett i sammenheng med syntax.

     

    Edit:

    For .. det finnes flere grader av idioti - noen ganger er det hensiktsmessig i ekstreme tilfeller.

  10. derfor tar operator= bare et argument og må derfor være medlem av klassen siden du ikke kan vite den andre typen hvis den ikke er medlem av klassen.

     

    Her er det ingen tvil hvilke typer det er snakk om:

    typename<T>
    T& operator=(T& a, RefCount<T>& b);
    
    RefCount<int> ri;
    int i;
    i = ri;

     

    Til og med dette burde vært lovelig:

    template<typename T1, typename T2>
    operator=(T1& o1, T2& o2);

     

    Jeg vil ha friheten til å gjøre, kanskje, idiotiske og gale ting.

    = burde være en ting man kan spesifisere for "hva som helst":

     

    * fra en egendefinert type til en innebyggd type

    * fra en egendefinert type til en egendefinert type

    * ...baaah...

     

    ..I grunn burde det ikke vært noen forskjell her mellom egendefinerte og innebyggde typer. Det er rart - men des mer man generaliserer og forenkler noe (noe som ofte kan være vanskelig), dess mindre blir språket og syntaxen; men mulighetene og kraften til å uttrykke seg øker proposjonalt.

     

    Så et språk som går 1-1 fra hode (problem space) til kode hadde vært fint, og hvis det siden - når man var ferdig, gikk å legge til detaljer som gjorde at koden matchet maskinens verden (solution space), hadde det vært fint. Tenker på å legge til ting (deklarasjoner o.l. f.eks.) som gjorde at det ble lettere for kompileren å lage rask maskinkode (mindre tid og rom) - dette går i flere språk.

     

    C++ har mange fordeler - men det er mye som ikke er godt gjennomtenkt og er unødvendig komplisert .. IMHO. Det kan hende noe av grunnen her er bakoverkompatibilitet med C, jeg har ikke tenkt så nøye på det.

     

    Edit:

    Jeg snakker altså ikke om C++ og standaren, jeg snakker om idéer rundt språket - og språk generellt egentlig.

  11. #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    
    using namespace std;
    
    template<class T>
    class RefCount {
    public:
    //Consturctors
    RefCount();
    RefCount(const T* new_value);
    RefCount(const RefCount& new_value);
    
    //Destructor
    ~RefCount();
    
    //General interface
    RefCount& make_unique() const;
    RefCount& clone() const;
    T& operator->();
    
    private:	
    T* p;
    std::size_t* refptr;
    }; // RefCount
    
    
    //Constructors, destructors
    template<class T>
    RefCount<T>::RefCount() 
    :p(T()), 
     refptr(std::size_t(1))
    {
    }
    
    
    template<class T>
    RefCount<T>::RefCount(const T* new_value)
    {
    if(!&new_value == p) {
    if(!*refptr--)
     delete p;
    *refptr--;
    this = &new_value;
    }
    }
    
    template<class T>
    RefCount<T>::RefCount(const RefCount& new_value)
    {
    if(!&new_value == this) {
    if(!this->refptr) {
     this.refptr = &new_value->refptr++;
     this.p = &new_value.p;
    }
    }
    }
    
    template<class T>
    RefCount<T>::~RefCount()
    {
    if(!*(--refptr)) {
    delete refptr;
    delete p;
    p = 0;
    }
    else {
    delete p;
    p = 0;
    }
    }
    
    //General interface
    
    template<class T>
    RefCount<T>& RefCount<T>::make_unique() const
    {
    return new T(p);
    }
    
    template<class T>
    RefCount<T>& RefCount<T>::clone() const
    {
    return new RefCount(*this);
    }
    
    template<class T>
    T& RefCount<T>::operator->()
    {
    return p;
    }
    
    
    // Av en eller annen grunn (som jeg ikke kommer på just nuh) går det ikke å bruke operator= slik i C++ ..
    
    /*
    //Non-members...
    template<class T>                      
    T& operator=(T& lhs, const RefCount<T>& rhs)  
    {
    //lhs = rhs->p;
    //return lhs;
    }
    */
    
    /*
    template<class T>
    RefCount<T>& operator=(RefCount<T>& lhs, const RefCount<T>& rhs)
    {
    if(!&lhs == &rhs) {
     if(lhs->p != rhs->p)
     	lhs.~RefCount();
     else {
     	&lhs = &rhs;
     	lhs->refptr++;
     }
    }
    return(lhs);
    }
    */
    
    /*
    template<class T>
    T& operator=(RefCount<T>& lhs, T& rhs)
    {
    lhs = RefCount<T>(rhs);
    return lhs;
    }
    */
    
    
    int main()
    {
    
    return(0);
    } // main
    

     

    Jeg har kun rettet på syntax-feil, hva som skjer (semantikken), har jeg ikke tittet på.

  12. Er vel ikke helt heldig det der nei - går fort noen ganger. Burde holdt meg til enten C++ eller C kanskje.

     

    Men må legge til at malloc/free er litt kjappere enn new/delete om jeg ikke tar helt feil, og når man skal allokere objekter uten konstruktør, innebygde f.eks., så er malloc/free greie tror jeg - selv under C++. (jeg tenkte ikke på dette da jeg skrev koden - så det er tilfeldig at det er slik)

     

    Edit:

    #include <iostream>
    #include <ctime>
    
    using namespace std;
    
    int main()
    {
    char* s;
    
    clock_t t = clock();
     for(unsigned int i = 0; i < 10000000; i++) {
     s = static_cast<char*>(malloc(1000));
     free(s);
    }
    cout << clock() - t << endl;
    
    t = clock();
     for(unsigned int i = 0; i < 10000000; i++) {
     s = new char[1000];
     delete[](s);
    }
    cout << clock() - t << endl;	
     
    return(0);
    } // main
    

     

    ..er i hvertfall det her - men det kan hende det varierer fra implementasjon til implementasjon.

  13. Ser ikke helt poenget sånn uten noen kontekst, men dette er i det minste mulig:

     

    #include <iostream>
    
    using namespace std;
    
    
    // "..sende char array reference.." array/peker går delvis for det samme.
    void format(char*& text)
    {
    cout << text << endl;
    } // format
    
    
    int main()
    {
    char text[] = "abc";
    char* temp = text;
    format(temp);
    return(0);
    }	// main
    

     

    Edit:

    Altså, har du kun statiske data for text, så gjør du jo dette:

    ...
    char* text = "hei";
    format(text);
    format("cba");
    ...

     

    Derimot hvis du har dynamiske, så bruker du:

    ...
    char* text = static_cast<char*>(malloc(.....)); // eller C++'s new .. 
    format(text);
    ...

     

    ..og disse to tingene fungerer - og er gyldige -- så hvorfor? Det har ingen hensikt å bruke char[] sånn jeg ser det uten noen sammenheng sånn-i-farta-her.

  14. Er det fordi programmet sansynligvis ikke er så krevende at det vil allokere så mye minne?

    Ja, jeg tar en sjans og regner det som sansynlig.

     

    ..men ha i bakhodet at minnet kan være allokert i fragmenter -- så har man (u)flaks, så treffer man innenfor sitt eget område uansett.

     

    Edit:

    Derfor er det kanskje greit å prøve flere ganger -- som i for-loopen, altså når jeg var ute etter en SIGSEGV.

  15. Oki,

    Tenk deg to programmer som ligger etterhverandre i datamaskinens minne:

     

    99 bytes med kode og data her (under kjøring)

     

    99 bytes med kode og data her (under kjøring)

     

    Hvis du tenker deg at OSet har som oppgave å passe på disse programmenes områder (som er anvist v.h.a. "quote-områder"). Program A har ikke lov til å se eller rote med B's minneområde, og omvendt. Videre, at man i starten (addresse 0) av program a har kode som refererer til nåværende addresse + 101. Da har program a gått utenfor sitt område og OSet avslutter det.

     

    Hadde A referert til nåværende addresse + 50 hadde dette gått helt greit (men fy flate å kjipt hvis det ikke var meningen at det skulle være 50 og noe annet enn det du forventet blir endret på) - siden dette fortsatt er innenfor A's område. Grunnen til at jeg satte stor verdi for for-loopen var for å garantere at den tilslutt gikk utenfor sitt område. Jeg kunne i grunn i stedet ha gjordt noe slikt:

     

    	int* a;
    cout << a[100000000] << endl;
    

     

    ..for å garantere at jeg havnet utenfor mitt eget område.

     

    Det som egentlig skjer (under Linux i hvertfall) er at OSet sender et signal til programmet. Poenget med dette signalet er at du skal kunne sette opp en signal-håndterer (en vanlig funksjon) som f.eks. lagrer data før du gir brukeren en vennlig beskjed om at programmet må/bør avsluttes.

     

    Når du ikke har satt opp en signalhåndterer gjør OSet det som er "default"; avslutter programmet.

     

    Håper ting ble klarere - ting er m.a.o. rimelig åpent og flatt - og du står fritt til å gjøre ganske mye rart du sansynligvis egentlig ikke vil gjøre.

     

    Må forresten legge til at du kan opprette/allokere noe som kalles "shared memory". Da kan flere programmer/prosesser ha tilgang til samme område, dette er veldig kjappt. (man shmget)

     

    Edit:

    Sjekk om du finner noe om "protected mode" på wikipedia eller v.h.a. google ellernoe. Dette er rimelig lavnivå - men det er greit å i det minste være klar over det. (jeg foretrekker i praksis å holde meg så høyt som mulig så lenge som mulig)

     

    Edit2:

    zirener (posten under): n.p. :]

  16. Det varierer litt fra implementasjon til implementasjon åssen de har gjodt det. Men under SBCL, som er den jeg bruker, kompileres koden (til native maskinkode) i det den kalles. Så det blir kanskje på en måte begge deler - både interpreted og kompilert.

     

    Jeg rekompilerer koden når jeg endrer den (mens selve programmet kjøres ja) - så det er ikke interpreter-basert, i normal forstand, i dette tilfellet.

     

    Angående å gjøre det samme med C++, så hadde det blitt vanskelig siden du (normalt) måtte ha stoppet programmet (etter kompilering og linking) for at det skulle "merke" at det var endret. Det kan hende dette er litt implementasjonsavhengig, linkeren måtte i så fall endret symboler/referanser i det kjørende programmet om det skulle fungert.

     

    Edit:

    Du kan så klart (i C/C++) lage en vanlig http-server (som gjordt her) og serve sider eller mer eller mindre dynamisk innhold, som her, men vet ikke helt hva du mente ..

     

    Må se på socket-programmering da - søk på beej @ google. Siden kan det være greit å søke på "http made easy" @ google.

×
×
  • Opprett ny...