GeirGrusom Skrevet 26. april 2011 Forfatter Del Skrevet 26. april 2011 Går jo an. Dette er mulig i C#. Men som regel så vil du bare bruke statisk typesetting, ettersom det er lite eller ingen jobb for programmereren, men gjør det absolutt 100% klart at programmet skal bruke int32 istedet for bigint eller omvendt, som er en antagelse compileren umulig kan gjøre korrekt for deg compile time. Lenke til kommentar
MailMan13 Skrevet 26. april 2011 Del Skrevet 26. april 2011 (endret) Ja, eller en kan velge å begynne i andre enden. D.v.s. at en starter med at alle variabler er dynamiske eller ikke har noen bestemt type deklarert for seg -- så legger kompileren til det den er sikker på selv, og tilslutt kan brukeren legge til typedeklarasjoner (og annet også) om han/hun ønsker dette. "Optimize last". Da vil kompileren generere kode som ikke gjør run-time typesjekking. Fungerer glimrende i mange språk det. F# er det språket jeg kjenner som kjører den helt ut, der nesten alt er utledet. Er jo det f.eks PyPy gjør for å få Python til å gå fort (Så kan man diskutere om RPython + PyPy er statisk eller dynamisk typet, skillelinjene begynner å bli litt fuzzy der). Fungerer fint for mange språk det. Dårligere for andre, i mange dynamiske språk er typen verdiavhengig. Hvis f.eks en int64 kan overflowe inn i en bigint eller en eller annen kompleks datatype må det nødvendigvis alltid legges på en sjekk på type/overflow uansett hva input var. Kanskje en divisjon mellom to heltall returnerer heltall hvis divisjonen går opp, eller en eller annen kompleks type hvis den ikke gjør det, da må det inn type og verdi-sjekker alle steder det brukes divisjon, osv... Endret 26. april 2011 av MailMan13 Lenke til kommentar
Gjest Slettet+9871234 Skrevet 26. april 2011 Del Skrevet 26. april 2011 (endret) Jeg starter her: Men det er ikke eneste grunnen til å hevde at dynamiske datatyper er noe tull: dynamiske datatyper fører ofte med seg noe annet jeg synes er tullete: implisitt konvertering av datatyper. og leser meg gjennom tråden. Ulike språk har ulike egenskaper etter min mening. Få språk er så strenge som Simula: "But after a while, most programmers realize that this means that a program is equipped with a safety net: many errors that programmers make when they construct programs are caught by this net before they lead to unpleasant effects. An example: A very expensive American space rocket crashed on its way to Venus a few years ago, because of an extremely trivial error in a FORTRAN program. A comma had be written as a point, and, as a consequence of that, the start of a special kind of repeat imperative was mistakenly read as an assignment imperative assigning a value to an undeclared variable. Had it been required to declare every variable in FORTRAN programs, the compiler would have discovered that the variable was undeclared and the error would have been caught much earlier than in the Atlantic Ocean." Professor Bjørn Kirkerud (1989): "Object Oriented Programming With Simula". Addison Wesley Publishing Company ISBN 0 201 17574 6. Page 31-32. PHP er som kjent tolket og løst typet. Jeg ser åpenbare fordeler med at variable kan endres ved runtime i PHP basert web kode. Jeg ser også åpenbare sikkerhetrisiko ved det. C er statisk typet og selvfølgelig sikrere av den grunn. Så min konklusjon: Alt avhenger av formålet. Alt dreier seg ikke bare om hurtighet og sikkerhet. Leser videre i tråden og håper ikke jeg gjentar allerede publiserte argumenter. Endret 26. april 2011 av Slettet+9871234 Lenke til kommentar
Gjest Slettet+9871234 Skrevet 26. april 2011 Del Skrevet 26. april 2011 (endret) Jeg har aldri kommet over "Oi! Nå hadde det vært kjekt med dynamiske datatyper". Ikke en eneste gang. Der hvor det hadde vært kjekt, tar generics og templates over på en mer elegant måte. Men generics er ganske dustete i Java (type erasure), så vi ser bortifra det. * Typesystemene i Java/C regnes vel ikke som særlig gode blandt de som holder på med type-teori, uten at jeg har særlig å backe opp det med selv. Merker forsåvidt tendensene selv når jeg har prøvd å løse noen "dynamiske" problemere i henholdsvis Java og Maude. Til dette vil jeg anbefale den klassiske boken: Gordon Blair, John Gallagher, David Hutchison and Doug Shephard (1991): "Object Oriented Languages, Systems and Applications." Pitman Publishing ISBN 0-273-03132-5 Noen sentrale sitater: Side 87: Two types are the same if they provide the same behaviours. Type is not Class. Class is fundamentally about implementation whereas type is concerned with abstract behaviour. Two objects of the same class will be of the same type. However, it is not necessarily the case that two objects of the same type will be of the same class. Se spesielt kapittel 4. Basic concepts III (Types, Abstract Data Types and Polymorphism). Endret 26. april 2011 av Slettet+9871234 Lenke til kommentar
GeirGrusom Skrevet 26. april 2011 Forfatter Del Skrevet 26. april 2011 Ja, eller en kan velge å begynne i andre enden. D.v.s. at en starter med at alle variabler er dynamiske eller ikke har noen bestemt type deklarert for seg -- så legger kompileren til det den er sikker på selv, og tilslutt kan brukeren legge til typedeklarasjoner (og annet også) om han/hun ønsker dette. "Optimize last". Da vil kompileren generere kode som ikke gjør run-time typesjekking. Fungerer glimrende i mange språk det. F# er det språket jeg kjenner som kjører den helt ut, der nesten alt er utledet. Er jo det f.eks PyPy gjør for å få Python til å gå fort (Så kan man diskutere om RPython + PyPy er statisk eller dynamisk typet, skillelinjene begynner å bli litt fuzzy der). Fungerer fint for mange språk det. Dårligere for andre, i mange dynamiske språk er typen verdiavhengig. Hvis f.eks en int64 kan overflowe inn i en bigint eller en eller annen kompleks datatype må det nødvendigvis alltid legges på en sjekk på type/overflow uansett hva input var. Kanskje en divisjon mellom to heltall returnerer heltall hvis divisjonen går opp, eller en eller annen kompleks type hvis den ikke gjør det, da må det inn type og verdi-sjekker alle steder det brukes divisjon, osv... F# deduserer typer, det er ikke dynamisk typet. Jeg ville nesten tro at alle funksjonelle språk er statisk typet, ettersom dynamisk typesetting ikke gir mening i et språk som tross alt ikke teknisk sett tillater variabler i utgangspunktet. Jeg er dog ikke noen ekspert på funksjonelle språk, og vet svært lite om det utover det lille jeg har tuklet med Haskell og F#. Lenke til kommentar
MailMan13 Skrevet 26. april 2011 Del Skrevet 26. april 2011 F# deduserer typer, det er ikke dynamisk typet. Jeg ville nesten tro at alle funksjonelle språk er statisk typet, ettersom dynamisk typesetting ikke gir mening i et språk som tross alt ikke teknisk sett tillater variabler i utgangspunktet. Jeg er dog ikke noen ekspert på funksjonelle språk, og vet svært lite om det utover det lille jeg har tuklet med Haskell og F#. Fullt klar over at F# er statisk. Skulle kanskje vært litt tydligere på poenget dog. Konklusjonen som var meningen å få frem er at det er ikke tilstedeværelsen av mange typenavn i kildekoden som gjør et språk statisk eller dynamisk. Selv om det er det som er den umiddelbare forsjkellen mellom språkene som vanligvis trekkes frem (Java/C++ vs Python). Bruker man et typesystem som ikke er like "broken beyond repair" som Java sitt så er det ikke alltid slik lenger. Lenke til kommentar
worseisworser Skrevet 26. april 2011 Del Skrevet 26. april 2011 (endret) Ja, eller en kan velge å begynne i andre enden. D.v.s. at en starter med at alle variabler er dynamiske eller ikke har noen bestemt type deklarert for seg -- så legger kompileren til det den er sikker på selv, og tilslutt kan brukeren legge til typedeklarasjoner (og annet også) om han/hun ønsker dette. "Optimize last". Da vil kompileren generere kode som ikke gjør run-time typesjekking. Fungerer fint for mange språk det. Dårligere for andre, i mange dynamiske språk er typen verdiavhengig. Hvis f.eks en int64 kan overflowe inn i en bigint eller en eller annen kompleks datatype må det nødvendigvis alltid legges på en sjekk på type/overflow uansett hva input var. Kanskje en divisjon mellom to heltall returnerer heltall hvis divisjonen går opp, eller en eller annen kompleks type hvis den ikke gjør det, da må det inn type og verdi-sjekker alle steder det brukes divisjon, osv... Ja, eller en kan si at en ikke ønsker slik sikkerhet eller oppførsel; det er opp til en selv hva som er viktig, eller hva dette "er" (sikkerhet/oppførsel), eller ikke for en i en gitt sammenheng. En kan si at en ønsker samme oppførsel som i C ("hjernedød" roll-around ved overflow), og kompileren vil da generere ennå enklere, "kjappere", kode. Endret 26. april 2011 av worseisworser Lenke til kommentar
Gjest Slettet+9871234 Skrevet 26. april 2011 Del Skrevet 26. april 2011 (endret) Ingen dynamisk kode nødvendig. Ettersom alle objekter implementerer Equals og operator == så er det ikke nødvendig å vite datatypen på feltene. Mikser dere ikke type med klasse, pholymorfi og overloading? Jfr. min foregående post. Sidenote: Merk at == er forskjellig fra === i Php. Endret 26. april 2011 av Slettet+9871234 Lenke til kommentar
GeirGrusom Skrevet 26. april 2011 Forfatter Del Skrevet 26. april 2011 (endret) Hva hvis en istedet for datatyper, heller definerer gyldige områder? Slik for eksempel: my_var = 0 constrain {0 -> 100} my_big = 0 constrain bigint my_person = null constrain person Og hvis en ikke sier noe annet, blir det dynamisk typet. Endret 26. april 2011 av GeirGrusom Lenke til kommentar
MailMan13 Skrevet 26. april 2011 Del Skrevet 26. april 2011 (endret) Ja, eller en kan si at en ikke ønsker slik sikkerhet eller oppførsel; det er opp til en selv hva som er viktig, eller hva dette "er" (sikkerhet/oppførsel), eller ikke for en i en gitt sammenheng. En kan si at en ønsker samme oppførsel som i C ("hjernedød" roll-around ved overflow), og kompileren vil da generere ennå enklere, "kjappere", kode. Er ikke kjent med noen dynamiske språk som lar meg bestemme det, hvilke? Dem jeg har vært borti gjør stort sett auto-overflow inn i double uansett, så må man inn med floor/ceil-funksjoner om man vil være sikker på hva man har med å gjøre. Endret 26. april 2011 av MailMan13 Lenke til kommentar
worseisworser Skrevet 26. april 2011 Del Skrevet 26. april 2011 (endret) Ja, eller en kan si at en ikke ønsker slik sikkerhet eller oppførsel; det er opp til en selv hva som er viktig, eller hva dette "er" (sikkerhet/oppførsel), eller ikke for en i en gitt sammenheng. En kan si at en ønsker samme oppførsel som i C ("hjernedød" roll-around ved overflow), og kompileren vil da generere ennå enklere, "kjappere", kode. Er ikke kjent med noen dynamiske språk som lar meg bestemme det, hvilke? Dem jeg har vært borti gjør stort sett auto-overflow inn i double uansett, så må man inn med floor/ceil-funksjoner om man vil være sikker på hva man har med å gjøre. CL-USER> (values (lisp-implementation-type) (lisp-implementation-version)) "SBCL" "1.0.47.30" CL-USER> (defun sum (x y) (+ x y)) SUM CL-USER> (sum 4 3) 7 CL-USER> (disassemble 'sum) ; disassembly for SUM WARNING: bogus form-number in form! The source file has probably been changed too much to cope with. ; 037CA30D: 498B442438 MOV RAX, [R12+56] ; no-arg-parsing entry point ; 12: 4883C010 ADD RAX, 16 ; 16: 48C740F852000000 MOV QWORD PTR [RAX-8], 82 ; 1E: 488968F0 MOV [RAX-16], RBP ; 22: 4989442438 MOV [R12+56], RAX ; 27: 4981BC24C800000017001020 CMP QWORD PTR [R12+200], 537919511 ; 33: 7402 JEQ L0 ; 35: CC0F BREAK 15 ; single-step trap (before) ; 37: L0: 488B55F8 MOV RDX, [RBP-8] ; 3B: 488B7DF0 MOV RDI, [RBP-16] ; 3F: 4C8D1C25E0010020 LEA R11, [#x200001E0] ; GENERIC-+ ; 47: 41FFD3 CALL R11 ; 4A: 480F42E3 CMOVB RSP, RBX ; 4E: 498B442438 MOV RAX, [R12+56] ; 53: 48C740F000000000 MOV QWORD PTR [RAX-16], 0 ; 5B: 48C740F800000000 MOV QWORD PTR [RAX-8], 0 ; 63: 4883E810 SUB RAX, 16 ; 67: 4989442438 MOV [R12+56], RAX ; 6C: 488BE5 MOV RSP, RBP ; 6F: F8 CLC ; 70: 5D POP RBP ; 71: C3 RET ; 72: CC0A BREAK 10 ; error trap ; 74: 02 BYTE #X02 ; 75: 18 BYTE #X18 ; INVALID-ARG-COUNT-ERROR ; 76: 54 BYTE #X54 ; RCX NIL CL-USER> (defun sum (x y) (declare (optimize (speed 3) (safety 0)) (fixnum x y)) (the fixnum (+ x y))) STYLE-WARNING: redefining COMMON-LISP-USER::SUM in DEFUN SUM CL-USER> (disassemble 'sum) ; disassembly for SUM ; 03AAFF4F: 4801FA ADD RDX, RDI ; no-arg-parsing entry point ; 52: 488BE5 MOV RSP, RBP ; 55: F8 CLC ; 56: 5D POP RBP ; 57: C3 RET NIL CL-USER> ;; ingen run-time typesjekking eller overflowsjekking o.l. ; No value CL-USER> (sum 4 3) 7 CL-USER> (sum most-positive-fixnum 1) -1152921504606846976 CL-USER> most-positive-fixnum 1152921504606846975 CL-USER> most-negative-fixnum -1152921504606846976 CL-USER> edit: Det er kombinasjonen av det å si at en ønsker full speed (speed 3) og ingen safety (safety 0) som gjør at kompileren genererer slik kode. Endret 26. april 2011 av worseisworser Lenke til kommentar
GeirGrusom Skrevet 26. april 2011 Forfatter Del Skrevet 26. april 2011 Hmmmm fiffig. Lenke til kommentar
MailMan13 Skrevet 26. april 2011 Del Skrevet 26. april 2011 Burde nesten kunne gjettet at Lisp støttet noe sånt, stilig Utledes x og y når du kaller den, eller er det helt statisk? Ser ut som du får ut asm med integer-add før du har kalt den, så funksjonen kanskje helt statisk typet? Lenke til kommentar
worseisworser Skrevet 26. april 2011 Del Skrevet 26. april 2011 Burde nesten kunne gjettet at Lisp støttet noe sånt, stilig Utledes x og y når du kaller den, eller er det helt statisk? Ser ut som du får ut asm med integer-add før du har kalt den, så funksjonen kanskje helt statisk typet? Denne er helt statisk. En har tilgang til compiler macroer som gjør at en kan dispatche til (eller generere blir vel egentlig mer riktig å si) forskjellige versjoner av SUM basert på type-informasjon som enten er eksplisitt tilgjengelig fra brukerens side eller inferret på andre vis, men dette er noe begrenset i SBCL desverre -- selv om Lisp som standard ligger åpen m.t.p. hva som er mulig å legge til her, altså som implementør av språket. Synes uansett blandingen av det statiske og det dynamiske er spennende, men spesielt med det dynamiske som utgangspunkt. Litt synd det ikke er mer utbredt -- etter hva jeg vet .. Lenke til kommentar
MailMan13 Skrevet 26. april 2011 Del Skrevet 26. april 2011 (endret) F# er hakket mer elegant siden den utleder det selv, for.eks kan man ha en funksjon: let sum(a, b) = a + b Men her lager ikke kompileren noe kode, men når man kommer videre: let c = sum(1.0, 2) Så kommer det ut en overload (int, double) som returnerer en double (siden int + double blir double). Hvis man senere plugger inn: let d = sum("abc", "123") Så kommer det ut en overload (string, string) som returnerer en string. Osv... Veldig behagelig måte å kode på, så lenge operatorene som er brukt er definert for argumentene man sender inn er det greit. Veldig kompakt syntaktisk og fremdeles 100% statisk. Det faller desverre litt sammen på metodekall, uten at jeg ser noe god grunn til at det ikke skulle fungere på samme måte. For eks. ser jeg ikke noe grunn til at jeg ikke bør kunne få si "let fn (x) = x.Length()" så lenge jeg bare kaller funksjonen med argumenter som har Length(), burde ikke være noe vanskligere å få til Endret 26. april 2011 av MailMan13 Lenke til kommentar
worseisworser Skrevet 26. april 2011 Del Skrevet 26. april 2011 (endret) F# er hakket mer elegant siden den utleder det selv, for.eks kan man ha en funksjon: let sum(a, b) = a + b Men her lager ikke kompileren noe kode, men når man kommer videre: let c = sum(1.0, 2) Så kommer det ut en overload (int, double) som returnerer en double (siden int + double blir double). Hvis man senere plugger inn: let d = sum("abc", "123") Så kommer det ut en overload (string, string) som returnerer en string. Osv... Veldig behagelig måte å kode på, så lenge operatorene som er brukt er definert for argumentene man sender inn er det greit. Veldig kompakt syntaktisk og fremdeles 100% statisk. Ah, ok. SBCL vil gjøre det samme når funksjonen (sum i dette tilfellet) er deklarert inline, men den har noen litt kjedelige begrensninger (edit: ganske like de du nevner helt til slutt etter redigering egentlig). Har noen tittet på Scala forresten? Endret 26. april 2011 av worseisworser Lenke til kommentar
GeirGrusom Skrevet 26. april 2011 Forfatter Del Skrevet 26. april 2011 Scala er en av de tingene jeg har lyst til å kikke på, men tid er mangelvare dessverre. Lenke til kommentar
Gjest Slettet+9871234 Skrevet 28. april 2011 Del Skrevet 28. april 2011 (endret) F# er hakket mer elegant siden den utleder det selv, for.eks kan man ha en funksjon: I C++ (om man ser stort på det, som en "supermengde av C") løses det enkelt ved templates og overloading, men det har vel med klasser og polymorfi og ikke datatype å gjøre. Egenproduserte "datatyper" klasser er ikke datatype. For å gjenta: Type is not Class. Ytterligere komplikasjoner oppstår ved subtyping. Se boken nevnt i min andre (#44) post. Endret 28. april 2011 av Slettet+9871234 Lenke til kommentar
worseisworser Skrevet 28. april 2011 Del Skrevet 28. april 2011 (endret) F# er hakket mer elegant siden den utleder det selv, for.eks kan man ha en funksjon: I C++ (om man ser stort på det, som en "supermengde av C") løses det enkelt ved templates og overloading, Siden dette er enkelt i C++; kan du poste litt kode? Endret 28. april 2011 av worseisworser Lenke til kommentar
MailMan13 Skrevet 28. april 2011 Del Skrevet 28. april 2011 (endret) I C++ (om man ser stort på det, som en "supermengde av C") løses det enkelt ved templates og overloading, Vil påstå at det (statisk utleding av typeinformasjon vs dynamiske typing) ikke er løst i C++ siden man, med et unntak jeg kommer på, eksplisitt må mate inn typenavn hele veien. Funksjonelle språk er alle funksjoner generiske/templates "by default", så man slipper navnespagettien som jager folk bort fra C++ og Java. C++ templates er ikke bundet til polimorfi spesielt. Man har litt covariance med templates som benytter de generelle reglene i C++. Arv og polimorfi er en av mekanismene man oppnår det med, men man kan like gjerne si: template <typename T> const T& max(const T& x, const T& y) { return x > y ? x : y; } Og kalle den opp med: double num = max<double>(1, 2.0); Ingen klasser involvert der, men vi kan sende inn noe annet enn T så lenge det er covariant i T. Egenproduserte "datatyper" klasser er ikke datatype. For å gjenta: Type is not Class. Ytterligere komplikasjoner oppstår ved subtyping. Se boken nevnt i min andre (#44) post. Du leser det som om det står "Class is not Type"? Endret 28. april 2011 av MailMan13 Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå