Gå til innhold

Hva er poenget med dynamiske datatyper?


Anbefalte innlegg

En implementasjon av et dynamisk språk kan UMULIG vite hva slags datatype som egner seg, og må typisk gjøre type-sjekking run-time. Ulempen kan du regne ut, for det går sterkt utover ytelsen å gjøre type-sjekking run-time. Se .NET DLR vs .NET CLR for eksempel. Min test med Vector double vs. dynamisk vector ga en 10x bedre ytelse på CLR.

Hvorfor denne besettelsen om at ytelse er eneste måleenhet for hvor bra et programmeringsspråk er?

Ja, siden statisk typede språk har mye mer typeinformasjon tilgjengelig i kompileringstid så kan de også gjøre mer aggressiv optimalisering. Men hvis et dynamisk språk lar meg løse et (ikke tidskritisk) problem på en elegant, lettleselig, og ikke minst vedlikeholdbar måte, hva betyr det om vector-klassen din er ti ganger raskere enn min? Enlighten me.

 

Og før du drar frem spillkortet: Ja, ytelseskritiske rutiner og algoritmer programmeres vanligvis i statisk typede språk (rightly so), men det betyr ikke at alt må gjøres slik. Python har f.eks en god del av modulene sine implementert i C.

 

float value = verdi gir samme syntaktisk informasjon ja, men det var heller ikke poenget.

Hva var poenget ditt da, GeirGrusom? For å svare på spørsmålet ditt: syntaksen er slik fordi den er slik i C. C++ støtter forøvrig "konstruktør"-syntaksen, og det er nok sikkert derfor GLSL bruker den.

  • Liker 1
Lenke til kommentar
Videoannonse
Annonse

En implementasjon av et dynamisk språk kan UMULIG vite hva slags datatype som egner seg, og må typisk gjøre type-sjekking run-time. Ulempen kan du regne ut, for det går sterkt utover ytelsen å gjøre type-sjekking run-time. Se .NET DLR vs .NET CLR for eksempel. Min test med Vector double vs. dynamisk vector ga en 10x bedre ytelse på CLR.

Hvorfor denne besettelsen om at ytelse er eneste måleenhet for hvor bra et programmeringsspråk er?

Ja, siden statisk typede språk har mye mer typeinformasjon tilgjengelig i kompileringstid så kan de også gjøre mer aggressiv optimalisering. Men hvis et dynamisk språk lar meg løse et (ikke tidskritisk) problem på en elegant, lettleselig, og ikke minst vedlikeholdbar måte, hva betyr det om vector-klassen din er ti ganger raskere enn min? Enlighten me.

 

Og før du drar frem spillkortet: Ja, ytelseskritiske rutiner og algoritmer programmeres vanligvis i statisk typede språk (rightly so), men det betyr ikke at alt må gjøres slik. Python har f.eks en god del av modulene sine implementert i C.

 

float value = verdi gir samme syntaktisk informasjon ja, men det var heller ikke poenget.

Hva var poenget ditt da, GeirGrusom? For å svare på spørsmålet ditt: syntaksen er slik fordi den er slik i C. C++ støtter forøvrig "konstruktør"-syntaksen, og det er nok sikkert derfor GLSL bruker den.

Spørsmålet mitt var "Hva er poenget med dynamiske datatyper"

Det var egentlig alt. Jeg har ikke kritisert Python eller noe annet språk, jeg har lurt på hvorfor de tar designvalget å ekskludere statisk typesetting, når ihvertfall ikke jeg kan se noen fordeler med dynamiske datatyper.

 

Når det gjelder casting, så var det selve castingen som var poenget, ikke typesettingen.

 

Jeg liker ikke dynamiske datatyper, og synes at når en lærer seg å programmere, er det lurt å få med seg datatyper også. En kommer til å dette borti det, og da er det fint og ikke sitte med et språk som nesten ser helt bortifra det.

Endret av GeirGrusom
Lenke til kommentar

Spørsmålet mitt var "Hva er poenget med dynamiske datatyper"

Det var egentlig alt. Jeg har ikke kritisert Python eller noe annet språk, jeg har lurt på hvorfor de tar designvalget å ekskludere statisk typesetting, når ihvertfall ikke jeg kan se noen fordeler med dynamiske datatyper.

Poenget? Det må vel være ett siden dynamiske typede språk er så populære og mye brukt. Siden andre har prøvd gjentatte ganger og feilet med å forklare deg det så tror jeg at du er nødt til å finne ut av det selv :-)

 

Når det gjelder casting, så var det selve castingen som var poenget, ikke typesettingen.

Selve castingen var jo den samme mellom de to språkene du viste. Det var bare syntaksen som var forskjellig.

 

Jeg liker ikke dynamiske datatyper, og synes at når en lærer seg å programmere, er det lurt å få med seg datatyper også. En kommer til å dette borti det, og da er det fint og ikke sitte med et språk som nesten ser helt bortifra det.

 

At et språk bruker dynamiske datatyper betyr ikke at det ser bort i fra typer. Det er forskjell på statisk vs dynamisk og strong vs weak typing. Det høres ut som om du tror at dynamisk typing impliserer weak typing.

Jeg anbefaler deg å lese http://en.wikipedia.org/wiki/Strong_typing. Og kanskje du burde skaffe deg litt mer erfaring innen forskjellige programmeringsspråk før du roper ut om hvor ubrukelige dynamiske typede språk er.

Lenke til kommentar

Spørsmålet mitt var "Hva er poenget med dynamiske datatyper"

Det var egentlig alt. Jeg har ikke kritisert Python eller noe annet språk, jeg har lurt på hvorfor de tar designvalget å ekskludere statisk typesetting, når ihvertfall ikke jeg kan se noen fordeler med dynamiske datatyper.

Poenget? Det må vel være ett siden dynamiske typede språk er så populære og mye brukt. Siden andre har prøvd gjentatte ganger og feilet med å forklare deg det så tror jeg at du er nødt til å finne ut av det selv :-)

 

Når det gjelder casting, så var det selve castingen som var poenget, ikke typesettingen.

Selve castingen var jo den samme mellom de to språkene du viste. Det var bare syntaksen som var forskjellig.

 

Jeg liker ikke dynamiske datatyper, og synes at når en lærer seg å programmere, er det lurt å få med seg datatyper også. En kommer til å dette borti det, og da er det fint og ikke sitte med et språk som nesten ser helt bortifra det.

 

At et språk bruker dynamiske datatyper betyr ikke at det ser bort i fra typer. Det er forskjell på statisk vs dynamisk og strong vs weak typing. Det høres ut som om du tror at dynamisk typing impliserer weak typing.

Jeg anbefaler deg å lese http://en.wikipedia.org/wiki/Strong_typing. Og kanskje du burde skaffe deg litt mer erfaring innen forskjellige programmeringsspråk før du roper ut om hvor ubrukelige dynamiske typede språk er.

Siden når var popularitet et argument for implementasjon av noe? Er språkene populært FORDI de har dynamiske datatyper? Neppe.

 

Jeg er fullstendig klar over hva strong og weak typing er, og jeg vet utmerket godt forskjellen mellom dynamisk og statisk typing. Men foreløpig har jeg ikke egentlig sett noen argumenter for dynamiske datatyper.

Det eneste jeg har nå fått servert er "Det er kjekt hvis du trenger det" og "Det er populært i mange scriptspråk".

Lenke til kommentar

Men foreløpig har jeg ikke egentlig sett noen argumenter for dynamiske datatyper.

 

Kan det hende at problemet ligger hos deg?

 

Det til side, hvordan ville din implementasjon av en heterogen container se ut? (I C++ eller Java -- jeg kan ikke C#). Svaret er at det lar seg ikke implementere uten å implementere et solid subsett av dynamisk typing, men da gjerne med sære begrensninger. Hva, sier du, du har aldri hatt behov for det? Vel, jeg bruker til stadighet

 

{"key1": "bar",
"key2": (1, 2, 3),
"key3": {"attr1": 1, "attr2": 2}}

 

... fordi det gjenspeiler behovet som programmet her. Det er naturlig å bruke en heterogen dict der og da. Ja, jeg vet at man kan marshalle alt til å være strings og konvertere fram og tilbake mellom de rette datatypene (lexical_cast til boost er egentlig veldig fin), men hvorfor det, annet enn å omgå typesystemet til språket? Hvorfor ikke si det problemområdet omtaler?

 

Nok et (veldig forenklet) trivielt eksempel (fra dagens kode):

 

def search_names(name_type):
   if not is_sequence(name_type):
       name_type = (name_type,)
   # ...
   return query("SELECT ... FROM ... WHERE name_type IN (%s)" % ",".join(name_type))
# end search_names

 

(koden er ikke slik i produksjon, siden det ville by på sql-injection, men ideen som er i produksjon er den samme). Fordelen er at klientkoden kan søke etter navn basert på en eller flere navnetyper. Og dersom det er flere, så kan man organisere disse slik det passer klientkoden (iterator, tuple, list, set, frozenset, dict):

 

search_names(last_name)
search_names((last_name, first_name))
search_names({last_name, full_name})

 

Heller ikke her strekker templates til, selv om man kan, antageligvis, spesialisere tilstrekkelig mange versjoner av template<typename T, typename U> U search_names(const T &name_type) for å få til halvparten av funksjonaliteten av snutten over med 100x økning i kodebasen.

 

Det eneste jeg har nå fått servert er "Det er kjekt hvis du trenger det" og "Det er populært i mange scriptspråk".

 

Det er veldig kjekt når problemet man skal løse kaller for det. Det er veldig kjekt når man ikke har bestemt seg for typene, men har heller kun en overordnet ide om hva slags grensesnitt disse typene skal tilby. Det er veldig kjekt når det er naturlig å kombinere flere typer et sted, uten at det skal dermed være nødvendig å bruke mange kalorier på å tvinge dem inn og ut av en eller annen fellesrepresentasjon (slik som strings).

 

En annen interessant observasjon er at de beste løsningene på projecteuler.net skrevet i eksempelvis Python er lysår foran den stipulerte tidsgrensen, mens de dumme løsningene i alle språk er lysår bak. Mesteparten av de oppgavene kan løses på under 1s UANSETT språkimplementasjon på noenlunde moderne maskin. Noen systemer er svært sensitive mot ressursforbruk, og der må man velge implementasjonen med omhu. Men svært mange systemer stiller større krav til andre egenskaper (introspeksjon, rask utvikling, muligheten for å utforske nye ideer), der dynamisk typing vil være veldig på sin plass.

Lenke til kommentar

Hva med f.eks Duck Typing?

 

I C# eksempelet der så må man spesifisere dynamic (aka runtime check) istedet for static for å få det til å fungere.

 

Edit : Flott å få det splittet ut til en ny tråd! Interessant diskusjon, men hadde ingenting i original tråd å gjøre :)

Endret av Terrasque
Lenke til kommentar

For ikke så lenge siden, leste jeg fort gjennom 'Code Conventions for The Java Programming Language', hvor det blant annet stod at man burde bruke parenteser for å gjøre det lettere å lese større logiske uttrykk..

 

Noe som i seg selv er selvsagt, men begrunnelsen var at man ikke skulle gå utifra at alle andre hadde like god peiling på operatørprioritet (operatør precedence) som det du hadde. Og da gikk det opp et lys for meg: Det finnes faktisk de som har (enda) mindre kunnskap enn meg, og som en dag kanskje skal lese kode jeg har skrevet..

 

Hva er poenget med dynamiske datatyper?

Jeg vil tro at eneste grunnen til å ha dynamiske datatyper, er for å gjøre det enklere for programmereren, så vedkommende slipper å forholde seg til forskjellige typer.. (!)

 

Tanken her er vel at det skal bli lettere å programmere, for det er langt fra alle som er såpass engasjerte, og ivrige som oss (vi henger tross alt på et diskusjonsforum en fredagskveld, for å diskutere programmering). Mange gir rett og slett f... i hvor lite effektivt et program kjører.

 

At dette igjen skaper store muligheter for dårlig og ulogisk kode, og i tillegg kan gjøre kjøringen tregere blir vel en annen sak.

Endret av greygenic
Lenke til kommentar

Jeg vil tro at eneste grunnen til å ha dynamiske datatyper, er for å gjøre det enklere for programmereren, så vedkommende slipper å forholde seg til forskjellige typer.. (!)

 

Igjennom hele levealderen til datamaskinen har det vært fokusert nettop på å gjøre ting lettere for programmereren. Husk, man begynte med maskinkode man skrev inn byte for byte via et sett med av/på switcher.

 

Hvis man fremdeles hadde gjort det, så tror jeg neppe man hadde hatt de avanserte programmene vi har nå. I tillegg til at det har blitt praktisk mulig med enda større programmer, har det også gjort det praktisk mulig å implentere mye kraftigere algoritmer. Som igjen gjør at man kan få mer ut av datamaskinen.

 

Jeg kan assembly, men jeg foretrekker python. Gjør det meg til en dårlig programmerer? De aller færreste programmene i dag er CPU bound, og jo mindre overhead fra programmerings-språket, dess lettere er det å fokusere på det problemet jeg prøver å få løst.

Lenke til kommentar

Jeg tenkte en del på dette med static / dynamic på veien hjem fra arbeid..

 

Static typing er, i bunn og grunn, støttehjul. Ikke så mye for programmerer og IDE (selv om det kan være greit), men for compileren. Det hjelper den å legge inn optimalisert kode for de variablene, før programmet blir kjørt.

 

Når koden blir kjørt av en interpreter, derimot, har man ikke den funksjonen. Der blir ikke en kodesnutt analysert før programmet er kommet så langt, og dermed har all informasjonen som trengs. Dette blir selvfølgelig litt mer shaky når JIT'ing kommer inn i miksen (selv om pypy folka mener de skal lage en som er uavhengig av variabel type).

 

Så, hvis man ikke trenger støttehjul (koden skal ikke compiles), hvorfor ha de med?

Lenke til kommentar

Dictionaryen funker jo fint i ethvert objektorientert språk. En trenger bare skrive mindre i Python.

 

Leste du hva jeg skrev overhodet? Hvordan implementerer du en heterogen container i et statisk typet språk? (dict-eksempelet i Python var bare en liten illustrasjon for hvorfor man skulle trenge det).

 

search_names ville jeg sagt var en temmelig typisk oppgave for lambdauttrykk, som er tilgjengelig i C++0x og C# (men ikke Java)

 

Mm... vær så snill, demonstrer hvordan du vil gjøre det i C++0x eller Java. Kravet er minst den samme funksjonaliteten som Python-snutten.

 

(Problemet, i tilfellet jeg var uklar opprinnelig, er at funksjonen må akseptere *en vilkårlig* type, forutsatt at den støtter visse operasjoner. C++ støtter dette i en viss utstrekning gjennom templates og operator overloading, men det er ikke i nærheten av å tilby en fleksibel løsning. Man kan lage en templateimplementasjon forutsatt at man får bare en type av gangen og man ikke trenger å skrive spesialkoden for hver type (template specialization vil kanskje være mulig for search_names, men spesialisering for hver type er fryktelig mye pes, utviklingsmessig).

Lenke til kommentar

Mm... vær så snill, demonstrer hvordan du vil gjøre det i C++0x eller Java. Kravet er minst den samme funksjonaliteten som Python-snutten.

 

C# løser det ihverfall utmerket, uten å oppgi statisk typing (her ligger nok .NET litt foran røkla. Mange språk har closure-implementasjoner, men jeg kommer ikke på så mange som har utrykkstrær på samme måte):

IEnumerable<SomeClass> SearchName(params string[] name_types)
{
   someEntity.Where(x => nameTypes.Contains(x.nametype));
}

Så kan man si SearchName("name1", "name2", osv); om det er det man vil

 

Eller løfte ut hele queryet ut hvis du vil ha det helt åpent:

IEnumerable<SomeClass> SearchName(Expression<<Func<SomeClass, bool>> filter)
{
   someEntity.Where(filter);
}

Litt mer å skrive på bruksiden, men tilgjengelig frihet til å filtrere på hva som helst.

 

Det siste blir litt tullete, da har man heller en repository som gir alle, så kan brukerene queryet på den:

 
IQueryable<SomeClass> GetAllSomeClass()
{
   return someEntity;
}

 

Vel, jeg bruker til stadighet

<snip>

... fordi det gjenspeiler behovet som programmet her

 

Hvis du har en forhandsdefinert sett av data av ulike typer tør jeg påstå at du like mye med en klasse å gjøre som en dictionary. Nå er forsåvidt ikke anonyme klasser/objekter noe ukjent fenomen i mange statiske språk heller.

Endret av MailMan13
Lenke til kommentar

C# løser det ihverfall utmerket, (...)

 

Nei, den gjør ikke det, noe du utmerket illustrerer med eksempelet ditt.

 

(...) uten å oppgi statisk typing (her ligger nok .NET litt foran røkla. Mange språk har closure-implementasjoner, men jeg kommer ikke på så mange som har utrykkstrær på samme måte):

IEnumerable<SomeClass> SearchName(params string[] name_types)
{
   someEntity.Where(x => nameTypes.Contains(x.nametype));
}

 

Takk, og der har du introdusert den begrensningen jeg forventet man skulle. Neste steg:

 

def search_names(name_types)
   if not issequence(name_types):
       name_types = (name_types,)
   # ...
   return query("SELECT ... FROM ... WHERE name_type IN (%s)" % 
                ",".join(str(x) for x in name_types))

 

Nå da? (Ja, det blir et neste steg til, hvor det kravet om at x skal ha __str__() vil fjernes, så det lønner seg å planlegge litt fram).

 

Så kan man si SearchName("name1", "name2", osv); om det er det man vil

 

Nei, det er ikke bare det man vil. Dessuten vil jeg kunne si:

 

search_names("name_full")
search_names(("name_full", "name_first"))
search_names({"name_full", "name_first"})

 

... og i utgave 2 vil jeg si:

 

search_names("name_full")
search_names(3)
search_names((u"name_full", "name_first"))

 

Prøv en gang til.

 

Hvis du har en forhandsdefinert sett av data av ulike typer tør jeg påstå at du like mye med en klasse å gjøre som en dictionary.

 

Setningen over gir ikke meningen på norsk. Kunne du prøve en gang til?

 

Nå er forsåvidt ikke anonyme klasser/objekter noe ukjent fenomen i mange statiske språk heller.

 

... som var helt ved siden av poegent mitt. Hvorfor er "heterogen container" så vanskelig å forstå?

Lenke til kommentar

Dictionaryen funker jo fint i ethvert objektorientert språk. En trenger bare skrive mindre i Python.

 

Leste du hva jeg skrev overhodet? Hvordan implementerer du en heterogen container i et statisk typet språk? (dict-eksempelet i Python var bare en liten illustrasjon for hvorfor man skulle trenge det).

Unnskyld, det var litt sent på dagen, så hadde litt dårlig tid.

 

var d = new Dictionary<string, object>();
d.Add("Key1", 123);
d.Add("Key2", "456");
d.Add("Key4", new var { FirstName = "John", LastName = "Connor" });
d.Add("Key5", new Dictionary<string, object>()
var d2 =d["Key5"] as Dictionary<string, object>;
if(d2 != null)
{
 d2.Add("key0", new object());
 d2.Add("key3", 123456);
}

foreach(var item in d)
{
 Console.WriteLine(item.Key + " = " + item.Value.ToString());
}

 

search_names ville jeg sagt var en temmelig typisk oppgave for lambdauttrykk, som er tilgjengelig i C++0x og C# (men ikke Java)

 

Mm... vær så snill, demonstrer hvordan du vil gjøre det i C++0x eller Java. Kravet er minst den samme funksjonaliteten som Python-snutten.

 

(Problemet, i tilfellet jeg var uklar opprinnelig, er at funksjonen må akseptere *en vilkårlig* type, forutsatt at den støtter visse operasjoner. C++ støtter dette i en viss utstrekning gjennom templates og operator overloading, men det er ikke i nærheten av å tilby en fleksibel løsning. Man kan lage en templateimplementasjon forutsatt at man får bare en type av gangen og man ikke trenger å skrive spesialkoden for hver type (template specialization vil kanskje være mulig for search_names, men spesialisering for hver type er fryktelig mye pes, utviklingsmessig).

Jeg tenkte på lambdauttrykk som en måtte å predikere select_names funksjonen fremfor select by example, men det er jo ikke akkurat det samme.

 

Men i C# har anonyme datatyper som er laget for akkurat dette:

var data = new var{ FirstName = "Abc", LastName = "Def" };
var items = select_names(data);

Lenke til kommentar

var d = new Dictionary<string, object>();
d.Add("Key1", 123);
d.Add("Key2", "456");
d.Add("Key4", new var { FirstName = "John", LastName = "Connor" });
d.Add("Key5", new Dictionary<string, object>()
var d2 =d["Key5"] as Dictionary<string, object>;
if(d2 != null)
{
 d2.Add("key0", new object());
 d2.Add("key3", 123456);
}

 

Aha, alt arver fra object og man har et system for autoboxing. Det var faktisk litt oppløftende. Der har jeg lært litt om C# i dag. Takk. Kan man teste typen til objektet presist? (i koden over, kan man teste hva typen til d["Key5"] er? Og da deklarere variabelen av denne typen for å manipulere videre på den? Eller holder det med en anonym typedeklarasjon? Hvis ja, hva slags runtime-sjekking på d2.Add() innebære? Evt. hvordan vet du at d["Key5"] peker på en Dictionary<string, object>? Eller, egentlig, hvorfor er "as Dictionary<string, object>" nødvendig?

 

Men i C# har anonyme datatyper som er laget for akkurat dette:

var data = new var{ FirstName = "Abc", LastName = "Def" };
var items = select_names(data);

 

Hvordan er disse implementert kontra dynamisk typede språk? For enhver operasjon utført på en var-type, runtimesystemet må nødvendigvis utføre en sjekk på at operasjonen er lovlig? Siden Python-koden taklet det fint, hvordan vil man skrive search_names() som tar enten en int, eller string eller en sekvens av disse blandet om hverandre?

 

Edit: Ah! Slik var det "Visual C# 2010 introduces a new type, dynamic. The type is a static type, but an object of type dynamic bypasses static type checking. In most cases, it functions like it has type object. At compile time, an element that is typed as dynamic is assumed to support any operation."

Endret av zotbar1234
Lenke til kommentar

Hvordan er disse implementert kontra dynamisk typede språk? For enhver operasjon utført på en var-type, runtimesystemet må nødvendigvis utføre en sjekk på at operasjonen er lovlig.

Dem er implisitt typet anonym klasse. "var someVar = ...;" betyr "finn typen på høyresiden". new {...} lager et nytt objekt av en anonym klasse, men den er fremdeles statisk og kompileren kan lage IL like effektivt som for en hvilke som helst annen statisk, ikke virituell, klasse.

 

Samme form for imlisitt typing som gjør at man for eksempel i F# normalt nevner svært få, eller ingen, typer ved navn i koden, og likevel vet kompileren alle typene up front. (google "Hindley–Milner" eller noe sånt)

 

"dynamic" nøkkelordet og DLR i C#4 (VS2010) er noe annet igjen, det er dynamisk binding, sammenlignbart med dynamiske språk.

Lenke til kommentar

var d = new Dictionary<string, object>();
d.Add("Key1", 123);
d.Add("Key2", "456");
d.Add("Key4", new var { FirstName = "John", LastName = "Connor" });
d.Add("Key5", new Dictionary<string, object>()
var d2 =d["Key5"] as Dictionary<string, object>;
if(d2 != null)
{
 d2.Add("key0", new object());
 d2.Add("key3", 123456);
}

 

Aha, alt arver fra object og man har et system for autoboxing. Det var faktisk litt oppløftende. Der har jeg lært litt om C# i dag. Takk. Kan man teste typen til objektet presist? (i koden over, kan man teste hva typen til d["Key5"] er? Og da deklarere variabelen av denne typen for å manipulere videre på den? Eller holder det med en anonym typedeklarasjon? Hvis ja, hva slags runtime-sjekking på d2.Add() innebære? Evt. hvordan vet du at d["Key5"] peker på en Dictionary<string, object>? Eller, egentlig, hvorfor er "as Dictionary<string, object>" nødvendig?

 

Du har to casting operasjoner i C#: operator as, og C-style casting.

 

Operator as returnerer null dersom et objekt ikke kan castes til den typen, og kan heller ikke caste value-types. C-style gir deg en exception, men kan caste value-types.

Derfor sjekker jeg om resultatet er null eller ikke, selv om det aldri vil bli null her.

 

Det er ikke lovlig å utføre aritmetiske operasjoner på object (utenom hvis en definerer dem dynamic, men det vil jeg helst ikke åpenbart) altså du kan ikke utføre noen som helst udefinerte operasjoner på noen objekter uten å caste først så lenge du bruker statisk typing.

Derimot har en selvsagt interfaces, men disse tillater ikke operatører (etter det jeg vet ihvertfall, uten at jeg egentlig har testet dette...)

Interfaces er lov å brukes på både value-types og reference-types, men en må være klar over at C# ofte vil boxe en value-type dersom du caster til et interface som den implementerer.

En vil uansett måtte caste dog.

 

Bruker du Dictionary<string, dynamic> forsvinner castingen dog.

 

edit: men da trenger en heller strengt tatt ikke Dictionary heller, og kan bruke ExpandoObject istedet.

 

dynamic expando = new ExpandoObject()
{
 expando.Key1 = "Abc";
 expando.Key2 = "Def";
 expando.Key3 = new ExpandoObject()
 {
   Key1 = "Abrakadabra"
   Key2 = 123456;
 }
}

 

Men jeg styrer unna dynamic.

 

Men i C# har anonyme datatyper som er laget for akkurat dette:

var data = new var{ FirstName = "Abc", LastName = "Def" };
var items = select_names(data);

 

Hvordan er disse implementert kontra dynamisk typede språk? For enhver operasjon utført på en var-type, runtimesystemet må nødvendigvis utføre en sjekk på at operasjonen er lovlig? Siden Python-koden taklet det fint, hvordan vil man skrive search_names() som tar enten en int, eller string eller en sekvens av disse blandet om hverandre?

 

Edit: Ah! Slik var det "Visual C# 2010 introduces a new type, dynamic. The type is a static type, but an object of type dynamic bypasses static type checking. In most cases, it functions like it has type object. At compile time, an element that is typed as dynamic is assumed to support any operation."

Korrekt.

 

Du ser ut til å ha funnet ut av det meste, men sjekken som må gjøres må gjøres igjennom reflection.

 

IEnumerable<T> search_names<T>(this IEnumerable<T> input, object example)
{
 Type T_type = typeof(T);
 Type ex_type = example.GetType();
 // Hent ut relevante felt i begge typene
 T_type.GetProperties();
 ex_type.GetProperties();
 // Mer kode som jeg ikke gidder å skrive
 // ...
 foreach(var item in input)
 {
   if(et_input_felt.GetValue(item) == et_eksempel_felt.GetValue(example))
     yield return item;
 }
}

 

Ingen dynamisk kode nødvendig. Ettersom alle objekter implementerer Equals og operator == så er det ikke nødvendig å vite datatypen på feltene.

Endret av GeirGrusom
Lenke til kommentar

Casting er en bra ting. Det gjør at uttrykket er fullstendig klart.

Hvorfor må ting være fullstendig klart helt ned på laveste nivå? En del av poenget med programmering er å kunne tenke i forskjellige abstraksjonsnivå. F.eks: jeg bryr meg egentlig ikke om number er et flyttall eller en BigInt så lenge resultatet eller korrektheten av programmet avhenger av det.

 

Dess mer unødvendig syntaks man legger til, dess tyngre blir det å lese koden.

En implementasjon av et dynamisk språk kan UMULIG vite hva slags datatype som egner seg, og må typisk gjøre type-sjekking run-time. Ulempen kan du regne ut, for det går sterkt utover ytelsen å gjøre type-sjekking run-time. Se .NET DLR vs .NET CLR for eksempel. Min test med Vector double vs. dynamisk vector ga en 10x bedre ytelse på CLR.

 

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.

Endret av worseisworser
Lenke til kommentar

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 konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...