Torben Mogensen header

Det første sprog (del 5)

I det foregående afsnit er der ikke taget beslutninger om datastrukturer – den eneste beslutning om data er, at der findes tal, og at heltal og kommatal er samlet i en enkelt type.

Gymnasieelever kender koordinater og vektorer, så en notation som (2,3) er umiddelbar forståelig. Derfor er det oplagt at bruge denne notation til par, men iøvrigt tillade andet og mere end bare par af tal, f.eks. bør (7,(2,3)) være lovligt. Endvidere er det ikke noget problem at udvide til tre eller flere dimensioner (selv om flerdimensionale koordinater og vektorer ikke normalt er gymnasiestof), så (3,4,5), (6,5,4,3) og så videre er oplagte at tage med.

Det er ligeledes oplagt, at par bygges med samme notation, som de vises med – altså (x,y) for at bygge et par af værdierne af x og y.

Mindre oplagt er det, hvordan man får fat i komponenterne i et par. Hvis p for eksempel er et punkt i planen (altså et koordinatpar), hvordan finder vi så de enkelte koordinater for p? En mulighed kunne være at bruge projektionsfunktioner såsom #1 og #2, så førstekoordinatet af p er #1(p). Man kunne også bruge indeks med subscript, såsom p1 (her er det meningen, at 1-tallet skal være rykket lidt ned, men BBCode kan ikke engang klare nedrykket tekst). Men jeg tror mere på symmetri mellem opbygning og inspektion, så man f.eks. kan skrive længdefunktionen i stil med

længde(p) = let (x,y) = p in x2+y2

(hvor det selvfølgelig er meningen, at 2-tallerne skal være hævede).

Jeg er dog ikke helt tilfreds med den her brugte syntaks for lokale definitioner. Den ligner den, der er brugt i SML og Haskell, men brugen af natursprogsord er lidt misvisende. Man kunne skrive noget i stil med

længde(p) = (x,y) = p; x2+y2

men så ligner det en sammenligning i stedet for en definition, eller endnu være en definition af af længde(p) er lig med (x,y), som igen er lig med p. Nogle sprog (f.eks. C og Haskell) vælger at bruge forskellige symboler for definition/tildeling (=) og sammenligning (==), men det bryder med brugernes erfaring, hvor = bliver brugt til begge dele. Så længe der kun er globale definitioner eller hvis sammenligning kun kan forekomme i betingede strukturer er der ikke noget stort problem, for så er konteksten tydelig.

Så, ligesom vi havde en notation, der gør det klart, at her starter (og slutter) en betinget struktur, så bør vi have en klar notation, der siger, at her starter (og slutter) en lokal definition.

En mulighed er at bruge en ækvivalens til Haskell's where-binding, dvs.

længde(p) = x2+y2 where (x,y)=p

Den er mere læselig og mindre misvisende end let-in notationen, men den er stadig lidt sprogchauvinistisk i sin brug af engelsk. En mulighed er at låne fra mængdenotation, hvor en lodret streg betyder "hvor", så man skriver

længde(p) = x2+y2 | (x,y)=p

som en pendent til mængdeudtryk i stil med {x2,y2 | (x,y) \in p} (hvor \in er "tilhører" symbolet). Denne notation er ikke universelt kendt i gymnasiematematik, men den kan bruges. Til gengæld betyder det, at min brug af | i betingede strukturer (se del 4) nok bør erstattes af noget andet, f.eks. semikolon.

Vi kan evt. tillade flere definitioner efter | adskilt af kommaer, f.eks.

længde(p) = xx+yy | (x,y)=p, xx = x2, yy = y2

Et spørgsmål er så, om de lokale definitioner er en del af udtrykket eller en del af funktionsdefinitionen, dvs. om man kan skrive

længde(p) = (xx | xx = x2)+(yy | yy = y2) | (x,y)=p

En fare ved dette ses, hvis vi undlader parenteserne: Betyder

xx | xx = x2 + yy | yy = y2

at xx er x2 + yy, eller afsluttes definitionen af xx efter x2?

En nærliggende mulighed er at kræve definitioner efter | eksplicit afsluttet, ligesom vi også valgte at afslutte en betinget konstruktion. Matematikere bruger ofte en lille firkant til at afslutte en definition, men den findes ikke i listen af HTML-symboler, så vi må finde på noget andet. Vi kunne bare falde tilbage på operatorpræcedens og sige, at | binder svagere end +, så xx herover faktisk ville være x2+yy. Men | er jo ikke en operator mellem to udtryk, så det kan være forvirrende.

Så for at mindske forvirringsmulighederne vil jeg begrænse lokale definitioner til at være en del af en definition i stedet for en del af et udtryk. Dermed er der ikke behov for eksplicit at afslutte definitioner.

Jeg vil stoppe her og kort opsummere dagens beslutninger:

  1. Lokale definitioner skrives i slutningen af en definition efter | og adskilt af kommaer.
  2. Par og længere tupler skrives med almindelig koordinatnotation og inspiceres via lokale definitioner med par/tupler af variabler på venstresiden.

Næste gang vil vi se på "enten eller" strukturer.

Kommentarer (11)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
#1 Jacob Christian Munch-Andersen

Er du sikker på at du ikke er lige lovligt meget i gang med at genopfinde den dybe tallerken? Det ser ud som om du forsøger at lave nye strukturer til stort set alt.

Hvad er der galt med:

funktion længde(p) return sqr(p[0]^2+p[1]^2) end function

Eller:

funktion længde(p) return sqr(p.x^2+p.y^2) end function

Alt efter om p er en tupel eller et objekt?

  • 0
  • 0
#2 Henning Makholm

Matematikere bruger ofte en lille firkant til at afslutte en definition, men den findes ikke i listen af HTML-symboler

Hvis du først har besluttet dig til at gå udenfor Ascii, forstår jeg altså ikke formålet med at begrænse sig til de tegn der tilfældigvis har defineret et symbolsk navn i HTML. Ifølge (X)HTML er symbolske referencer som ∀ blot praktiske forkortelser for numeriske unicode-referencer (∀ bliver til ∀ og sådan er det hele vejen). Hvis brugerne hverken skal se eller taste præsentationsrepræsentationen selv, kan jeg ikke se hvilken fordel du får ved at begrænse sig til symbolske navne.

Hvis du vil have en QED-firkant i dit sprog kan den vises som □. Det er da ikke spor sværere at arbejde med end ≤.

  • 0
  • 0
#3 Bjarke Walling

Der er ikke meget nyt i udpakning af tupler. Det findes i hvert fald i både Python og Ruby: [code=python]p = (1,2) (x,y) = p[/code] Det smarte er at programmøren selv kan navngive de enkelte elementer. Syntaksen for at definere funktioner med lokale variable er måske ny, men jeg synes egentlig det virker meget intuitivt.

  • 0
  • 0
#4 Morten Kromberg

Og ikke kun i Python og Ruby: I APL blev notationen indført omkring 1983:

(X Y) <- 3 4

Her er det dog ikke nødvendigt at udpakke elementerne i en tupel for at beregne længden af en vektor (uanset antal dimensioner):

{p+.2)0.5

  • er potens-opløftning i APL (multiplikation skrives ×). +.* er summen af resultaterne af potens-opløftningen.

Man kan også arbejde direkte på "nested tuples" - i APL er der ikke behov for komma mellem elementerne. Så hvis vi har en x og to y værdier kan vi beregne de to længder i et hug uden udpakning eller loops:

(3 (4 5)+.2)0.5 5 5.830951895

  • 0
  • 0
#5 Torben Mogensen Blogger

Ja, du har ret. Jeg havde brugt en liste over HTML symboler, som jeg fandt på nettet, og fandt ikke firkanten der.

Jeg har dog lavet lidt flere overvejelser siden jeg skrev indlægget, og kan se nogle ulemper ved at lægge de lokale definitioner efter funktionskroppen: Beregningsrækkefølgen er ikke længere ventre-mod-højre. Hvis en funktionskrop er stor, vil de lokale definitioner endvidere ligge langt efter brugen af de definerede navne, så man skal læse forud for at se dem.

Så det er muligt, at jeg alligevel ender med foranstillede definitioner.

  • 0
  • 0
#6 Torben Mogensen Blogger

Der er ikke meget nyt i udpakning af tupler. Det findes i hvert fald i både Python og Ruby

Og ikke kun i Python og Ruby: I APL blev notationen indført omkring 1983

Og det findes også i ML, Haskell og mange andre deklarative sprog. ML brugte det allerede i 1973, og er nok ikke det første eksempel.

Jeg har ikke sagt, at det er en ny ide, men det behøver den heller ikke at være.

  • 0
  • 0
#7 Anonym

Kan vi evt. starte en diskussion om hvorvidt et klassisk og matematisk funderet sprog er en god indgangsvinkel til at få gymnasieelever (og andre) til at interessere sig for IT-faget?

Hvis det drejer sig om at lokke "ikke nørderne" til, vil jeg anbefale noget a'la gamemaker, hvor det er muligt at programmere mindre spil uden at skrive en eneste linie kode. Man sætter i stedet en række parametre for hver entitet, der så opfører sig som befalet.

På den måde kan man fokusere på at få sit "program" til at gøre det man gerne vil have det til, i stedet for at hænge fast i syntaktiske problemer.

Basalt set er programmering jo bare en række instruktioner der skal tolkes. I nogle tilfælde af en computer i andre af husfædre m/k.

Brunede kartofler: Drys sukker på en tør pande og smelt det uden at røre. tilsæt smør lad det bruse op og kom kartoflerne på panden. Ryst jævnligt panden, så sukkerlagen fordeler sig jævnt. Hvis kartoflerne er kolde, når de kommer på panden vil sukkeret måske stivne, men skru blot lidt op for varmen, så smelter det igen.

Fra: http://www.maduniverset.dk/opskrift.php/3412/Svinekoed-opskrifter/Hambur...

er jo et glimrende eksempel på et program der er skrevet i naturligt sprog. (Dekleration og tildeling er udeladt af pladshensyn).

Så generelt mener jeg ikke at en matematisk tilgang til programmering nødvendigvis er en god idé. Man skræmmer i høj grad de personer væk, der ikke snakker flydende matematik eller finder det interessant.

  • 0
  • 0
#8 Morten Kromberg

Rasmus Tønnesen: Er et matematisk funderet sprog en god indgangsvinkel til at få gymnasieelever (og andre) til at interessere sig for IT-faget?

Det er et godt spørgsmål... Og jeg bør vel starte med at undskylde at jeg dukker op midt i denne artikelserie med et par "i APL gør vi det anderledes" opstød på tidspunkter som mange af Jer sikkert mener er upassende. Jeg lover at holde en pause efter dette indlæg ;-)

Hvis vi tager en af de klassiske begynder-opgaver som eksempel: "Læs en fil og skriv ud de 5 hyppigst forekommende tegn, med en optælling af hvor tit de forekommer", kunne en APL-løsning se ud som følger (jeg har skiftet nogle APL-tegn ud med deres navne med # som præfiks):

tekst <- HTTPGet 'http://www.cnn.com' unikke <- #unique tekst frekvens <- +/unikke #null.=tekst sortcol2 <- {w[#downgrade ;w[;2];]} 5 #take [1]sortcol2 unikke,[1.5]frekvens (blank) 5481 n 5447 e 5133 i 4755 t 4320

Hvorvidt løsninger er mere abstrakt eller skræmmende end en klassisk løsning er jeg nok inhabil til at udtale mig om. Men det er rigtigt at denne form for løsning ikke kræver at eleverne lærer noget om loops, conditionals, eller sortering. Så hvis DET, der er formålet, er den matematiske notation helt klart "upassende" i undervisningen.

Spørgsmålet bliver så HVAD gymnasie-elever skal bruge IT til. Og her er jeg nok enig i at værktøjer som "gamemaker" er vejen frem hvis man vil vække interessen for programmering uden at forskrække.

Det som piner MIG er at man anbefaler at folk som HAR en matematisk indgangsvinkel (ingeniører, økonomer, og også nole gymnasie-elever) bruger sprog som Java eller C# som værktøjer til udvikling af analytiske applikationer.

  • 0
  • 0
#9 Torben Mogensen Blogger

Kan vi evt. starte en diskussion om hvorvidt et klassisk og matematisk funderet sprog er en god indgangsvinkel til at få gymnasieelever (og andre) til at interessere sig for IT-faget?

Valget af matematik som udgangspunkt for sproget er, at det er det eneste fag, hvor skoleelever har set en formel notation. Hvis man brugte formelle notationer i andre fag, så havde de været udmærkede udgangspunkter.

Med hensyn til Gamemaker og lignende, så spørgsmålet, om man lærer at programmere ved at bruge disse værktøjer.

Og ja, jeg har brugt meget tid på syntaks, men det er ført efter begrebet er besluttet. Og jeg mener, at syntaks er vigtig for nybegyndere. For mere erfarne programmører er det mindre væsentligt, med mindre man går over i det absurde eller ekstremt ordrige.

  • 0
  • 0
#10 Jon Loldrup

<quote=Torben>længde(p) = x2+y2 where (x,y)=p

Den er mere læselig og mindre misvisende end let-in notationen, men den er stadig lidt sprogchauvinistisk i sin brug af engelsk.

Jeg forstår ikke hvorfor du er så fobisk mod at proge et natursprogsord. Var din oprindelige ide ikke netop at bruge termer og syntaks som gymnasieelever var bekendt med? Din indvending mod natursprogsord plejer at være når de i natursproget har en lidt anden betydning end den der ønskes i programmeringssproget, men i dette tilfælde er der da fuld ækvivalens mellem den natursproglige og den i programmeringssproget ønskede betydning af ordet "where"!

  • 0
  • 0
#11 Jon Loldrup

Hvordan man programmerer, med imperative sprog: Man formulerer sit mål (deklarativt) Man deler målet op i mindre mål (deklarativt) Man oversætter de mindre mål til imperativer Man nedfælder imperativerne i programmeringssprogets syntaks

Hvordan man programmerer, med (rent) deklarative sprog: Man formulerer sit mål (deklarativt) Man deler målet op i mindre mål (deklarativt) Man nedfælder deklarationerne i programmeringssprogets syntaks

Hvordan man programmmerer, med (rent) deklarative sprog, hvor syntaksen er ikke-eksisterende, eller så intuitiv at man ikke skal tænke over at man overhovedet benytter den (Gamemaker? Lego mindstorms' IDE?): Man formulerer sit mål (deklarativt) Man deler målet op i mindre mål (deklarativt) Man nedfælder deklarationerne stort set uden at få brug for at tænke sig om for at gøre det.

Det svære i programmering er ikke at oversætte til en given syntaks. Det er allerhøjst forvirrende (i starten). Det svære er at analysere og nedbryde sit problem så det bliver så atomiseret at det kan formuleres så en computer kan forholde sig til det. Det er altså det at analysere sine højniveau deklarationer, og bryde dem ned til lavere niveau deklarationer der er selve kunsten i programmering, og det er helt forskelligt fra det at være god til at oversætte atomare deklarationer/imperativer til en given syntaks Derfor kan man godt lære god programmering uden at lære sidstnævnte. Det betyder så igen at man godt kan lære god programmering ved at lære "peg-og-klik"-programmering, som f.eks. Gamemaker og LEGO Mindstorms (vidstnok) tilbyder.

Jeg er ikke helt sikker på hvad Torben mener med at syntaks er vigtig for nybegyndere. Jeg håber han mener det i den forstand at det er vigtigt at det bliver så transparent for brugeren som muligt..

  • 0
  • 0
Log ind eller Opret konto for at kommentere