Ontwerp nieuwe programmeertaal

Pagina: 1 2 Laatste
Acties:

Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Verwijderd schreef op zaterdag 08 november 2008 @ 21:23:
[...]

OK, prima reden. Maar ook een reden om helemaal vanaf 0 te starten terwijl je ook al de VMs van Java, .NET/Mono, LLVM, etc. hebt?
Doe jij eens zoeken op LLVM en prototype in dit topic ;)
Ik kan wel degelijk voorbij Brainfuck zelf kijken, en vond jouw blog erg interessant, maar gaf alleen aan dat je dat in elke compiler die byte arrays aankan kunt doen. C/C++, C#, VB.NET, Delphi, noem maar op...
Ik zou eerder geneigd zijn om over "een lint/tape" te spreken dan "byte arrays" ;). Brainfuck kan met elke taal geimplementeerd worden die turing complete is, omdat het zelf turing complete is, wat ik ook op m'n blog heb staan ;-) .

[ Voor 47% gewijzigd door prototype op 08-11-2008 23:56 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Tja, ik ben programmeur, geen wiskundige...

Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Even een kleine bump. Enkele weken geleden ben ik bezig geweest met het bestuderen van LLVM en alhoewel iedereen er wel wat lovends over te zeggen heeft, heb ik er eigenlijk steeds minder lovende dingen over te zeggen. Met name de documentatie en compleetheid van code, waarvan de eerste zwaar achterhaald is ten opzichte van het laatste. Het is me nu al vele keren overkomen dat bij het spelen van LLVM aan de hand van documentaties ik gewoon regelrechte leugens achterhaal over beweringen van dingen die geimplementeerd zijn die in werkelijkheid __niet__ geimplementeerd zijn. Dit heeft bij mij geleid tot het alombekende de code is de documentatie syndroom wat mij geenszins bevalt...

Met dit in het achterhoofd ben ik vorige week begonnen met de eerste paar AST klassen te schrijven voor dit project, voorlopig zonder LLVM. Nu echter Parrot 1.0 ook gereleased is is het misschien grappig om hier ook naar te kijken. Punt is alleen dat ik stiekem de VM eigenlijk wel van scratch zou willen implementeren om een betere en diepere kennis te krijgen over dit onderwerp.

Vrije tijd heb ik niet veel, maar ik probeer er zoveel mogelijk van wat ik heb in dit project in te stoppen en ook verslag te doen van wat er momenteel gedaan wordt: leuk voor mensen om te lezen denk ik die zich ook altijd al bezig hebben willen houden met het bouwen van een programmeertaal van scratch en het helpt denk ik eventueel ook bij het discussieren van language features en hoe deze geimplementeerd dienen te worden. Hierbij kan ik niet op elk punt ingaan omdat dat meer tijd zou kosten om te bespreken dan om iets geimplementeerd te krijgen. Bij deze zou ik dan ook eventueel een informele oproep willen doen aan mensen die graag mee zouden willen helpen: misschien niet geheel verassend, maar daarbij vraag ik voor de "core" op z'n minst een redelijk goede kennis van formele talen/compiler construction, "algoritmen/datastructuren en complexiteit", source version control en C++. Zelf ben ik geen expert in allen van deze (ik ben pas 23 ;-)) , en het is dan ook dat ik dit beschouw als een leerzame ervaring waarbij we van elkaar het e.e.a. zouden kunnen leren.

Mijn streven is vooralsnog een Ruby/Smalltalk/Python verpakt in PHP/java achtige syntax (het curly brace syndroom ;-)) daar ik de eerstgenoemde talen gewoon praktisch familie van elkaar beschouw en superieur ook in featureset tov laatstgenoemde :+ . Dit betekent dus in eerste instantie een hybride strong- en weaktyped dynamische taal: typehinten zoals dat in PHP b.v. mogelijk is zal ook hier toegestaan moeten zijn waarbij we dan zelfs nog statische optimalisaties zouden kunnen doen. Je zou het echte doel dan ook misschien kunnen beschouwen als PHP opnieuw ontwerpen zonder rekening te hoeven houden met backwards compatibility en in dit geval dus ook de inconsistenties weg kunnen halen. Achterlijke dingen zoals bij lambda's nog aan moeten geven aan wat voor scope hij moet binden moeten daarbij ook "oprotten" ;-)

Additionele dingen zoals Ahead of time compilation evenals just in time compilatie vind ik ook interessant om naar te kijken, zeker als blijkt dat tegen de tijd dat we hier eventueel aan toe zouden komen LLVM ook gewoon in orde is, die biedt namelijk faciliteiten voor deze dingen. Of we het afkrijgen weet ik niet, maar leerzaam zal het zeker moeten zijn denk ik. Dus laat ik maar eerst eens vragen of er een paar knappe koppen hier zijn die hier eventueel aan mee zouden willen werken. Uiteindelijk hoop ik namelijk op dit of een gerelateerd onderwerp af te kunnen studeren :-)

Acties:
  • 0 Henk 'm!

  • link0007
  • Registratie: Augustus 2006
  • Niet online
hoe dynamisch word de taal trouwens? Bij sommige talen kan je je eigen infix operators toevoegen, wat ik echt een immens handige feature vind:

code:
1
2
and := (a,b) => {a? {b? true : false} : false};
infix 2 left _&&_ => and;


Geweldige toevoeging voor een taal IMO :)

Zullen vast nog wel meer talen zijn die dit bieden, maar ik ben het nog niet vaak tegen gekomen

[ Voor 14% gewijzigd door link0007 op 29-03-2009 16:09 ]

IF IF = THEN THEN THEN = ELSE ELSE ELSE = IF;


Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 20:52

RayNbow

Kirika <3

link0007 schreef op zondag 29 maart 2009 @ 16:06:
code:
1
2
and := (a,b) => {a? {b? true : false} : false};
infix 2 left _&&_ => and;
Is rechtsassociatief niet zinniger (vanwege evt. short circuiting indien de argumenten niet strict geevalueerd worden)?

De Haskell definitie:
Haskell:
1
2
3
infixr 3 &&
True  && x = x
False && _ = False

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Maakt eigenlijk geen zak uit, of a && b && c nou geparsed wordt als a && (b && c) of (a && b) && c, in alle twee de gevallen wordt eerst a geëvalueerd, dan b, dan c.

.edit: hoewel het wel zo is dat als a false is, 'false && c' nog een extra aanroep van de operator is, terwijl hij bij 'false && (b && c)' al direct kan stoppen. Maar in gegenereerde code zullen de twee manieren identiek zijn.

[ Voor 41% gewijzigd door .oisyn op 29-03-2009 17:03 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

link0007 schreef op zondag 29 maart 2009 @ 16:06:
hoe dynamisch word de taal trouwens? Bij sommige talen kan je je eigen infix operators toevoegen, wat ik echt een immens handige feature vind:

code:
1
2
and := (a,b) => {a? {b? true : false} : false};
infix 2 left _&&_ => and;


Geweldige toevoeging voor een taal IMO :)

Zullen vast nog wel meer talen zijn die dit bieden, maar ik ben het nog niet vaak tegen gekomen
Aangezien alles een object zal worden, kun je de infix operator die jij hier voorstelt gewoon zien als een methode die je aanroept op 't object aan de linkerkant van jouw "infix operator". Als argument krijgt het dan het "rechtergedeelte". Hier zou nog eventueel syntactisch suiker voor geboden kunnen worden, e.g. voo rmethoden die aangeduidt worden als zijnde operatoren, is het toegestaan dan om de record notation dot en eventueel de haakjes weg te laten. Moeten we alleen nog even heel goed over nadenken of dat wenselijk is. Verder hoef je je geen zorgen te maken over evaluatie van dit soort expressies, dat zal gewoon shortcircuited gebruiken by default.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Ondersteun je de bekende cast expressions? En zo ja, hoe? :P Ze zijn namelijk zo ambigu als de pest als je nog niet weet of een identifier een type aangeeft.

(a)+b

Is dat een optelling, of de expressie +b gecast naar een a. In C++ kom je nog weg door type info tijdens het parsen terug te voeren aan de lexer, zodat je voor types andere productieregels kunt gebruiken. Als je wilt dat je types kunt gebruiken voor je ze gedefinieerd hebt kan dat niet meer, en zul je een superset van de grammatica moeten verzinnen, waarna je in de AST gaat kijken wat er daadwerkelijk bedoeld wordt (en daarbij mogelijk nog parse errors kunt geven omdat je gebruikte grammatica meer toestaat dan de taal zelf). Maar zo'n supergrammatica verzinnen is al een moeilijkheid op zich. Je zou bijv. de productieregel '(' expression ')' expression kunnen gebruiken, zodat (a) een expression is en +b ook, maar dat conflicteert weer met de binaire + operator.

[ Voor 15% gewijzigd door .oisyn op 29-03-2009 22:08 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • unclero
  • Registratie: Juni 2001
  • Laatst online: 08:18

unclero

MB EQA ftw \o/

prototype schreef op zaterdag 28 maart 2009 @ 17:42:
Punt is alleen dat ik stiekem de VM eigenlijk wel van scratch zou willen implementeren om een betere en diepere kennis te krijgen over dit onderwerp.
Is inderdaad buitengewoon interessante materie ;).

* unclero is stiekem ook al een tijdje bezig met zijn eigen VM'tje

Wellicht tijd voor een "Show je programmeertaal" topic? :>

Quelle chimère est-ce donc que l'homme? Quelle nouveauté, quel monstre, quel chaos, quel sujet de contradiction, quel prodige!


Acties:
  • 0 Henk 'm!

  • user109731
  • Registratie: Maart 2004
  • Niet online
.oisyn schreef op zondag 29 maart 2009 @ 20:42:
Ondersteun je de bekende cast expressions? En zo ja, hoe? :P Ze zijn namelijk zo ambigu als de pest als je nog niet weet of een identifier een type aangeeft.
FWIW, in Java werkt het zo:
code:
1
2
3
CastExpression:
        (PrimitiveType Dimsopt) UnaryExpression
        (ReferenceType) UnaryExpressionNotPlusMinus

En voor C#.
From the disambiguation rule it follows that, if x and y are identifiers, (x)y, (x)(y), and (x)(-y) are cast-expressions, but (x)-y is not, even if x identifies a type. However, if x is a keyword that identifies a predefined type (such as int), then all four forms are cast-expressions (because such a keyword could not possibly be an expression by itself).
Volgens beiden is (a)+b alleen een cast als a een primitive/predefined type is. Dat lijkt mij ook de enige mooie oplossing voor een dynamische taal: het is goed gedefinieerd en je hoeft niet at runtime nog eens te kijken wat de bedoeling is...

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Hmm ok interessant :). Ik ben momenteel aan het spelen met Coco/R, daarmee kun je custom predicates voor productieregels schrijven (die bijvoorbeeld de tokenstream uitlezen om te kijken wat er komen gaat), waardoor hij feitelijk LL(inf) wordt ipv de LL(1) die hij normaal is. M'n huidige implementatie kijkt of er alleen tokens voorkomen die in een type mogen zitten, maar dat is niet genoeg - dan zal hij een expressie als (a, b)+c ook als cast zien. Wat ik nu probeer te doen is de parser iets aan te passen zodat hij simpelweg probeert of het gedeelte tussen haakjes is te parsen als type en zo niet te backtracken (wat het effectief een GLL parser maakt).

En m'n regel is dus: als het te parsen is als een type, dan is het een cast expression. Maar ik heb er even niet bij stilgestaan dat je op die manier nooit meer een optelling of aftrekking kan schrijven. Ik denk dat ik de regel uit Java en C# dus maar overneem :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Ik ben momenteel bezig met me in te lezen in Parser combinatoren omdat een van de dingen waar ik me altijd aan ergerde bij het specificeren van een taal was dat ik het niet goed kon opdelen in kleinere beter onderhoudbare stukken qua grammatica. Bij deze dus even kijken naar of ik kleinere parser programma's kan combineren en zo wat meer flexibiliteit kan krijgen misschien: ook zou het schijnbaar ambigue taal parsen eenvoudiger moeten maken en daar ben ik eigenlijk ook wel in geinteresseerd omwille van een paar taal constructies. Misschien niet de beste redenen om dit te bestuderen, maar misschien komt er nog wat interessants uit. Een wat uitgebreidere verslaggeving volgt dan ook snel als RayNbow al niet ondertussen verteld heeft hoe gaaf 't in haskell is ;-)

[ Voor 14% gewijzigd door prototype op 30-03-2009 22:23 ]


Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 20:52

RayNbow

Kirika <3

prototype schreef op maandag 30 maart 2009 @ 22:21:
[...] ook zou het schijnbaar ambigue taal parsen eenvoudiger moeten maken en daar ben ik eigenlijk ook wel in geinteresseerd omwille van een paar taal constructies.
Als je werkt met list of successses, dan kan je op sommige punten tijdens het parsen wat ambiguiteit tegengaan (denk bijv. aan de problemen in LR(k) met shift/reduce conflicten). Je houdt in feite gewoon alle mogelijke parses tot nu toe bij en soms vallen er een paar mogelijkheden af en soms komen er paar mogelijkheden erbij.

Als echter de gehele grammatica ambigu is, dan heb je na afloop van het parsen dus niet 1 enkele mogelijke parse. De vraag is of dit wenselijk is.

(Aan welke taalconstructies zat je trouwens te denken?)
als RayNbow al niet ondertussen verteld heeft hoe gaaf 't in haskell is ;-)
Het is gewoon gaaf in Haskell vanwege de lichte syntax om dingen aan elkaar te knopen. :p

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
RayNbow schreef op maandag 30 maart 2009 @ 23:19:
Als echter de gehele grammatica ambigu is, dan heb je na afloop van het parsen dus niet 1 enkele mogelijke parse. De vraag is of dit wenselijk is.
Dat doen de generalized parsers dus. Bij ambiguïteiten parsen ze gewoon alle mogelijkheden. Tijdens of na het parsen kun je vervolgens de conflicts resolven adhv een semantische analyse van de rest van het programma.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Kunnen we niet beter gewoon eerst een eigen parser generator maken? :P

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 20:52

RayNbow

Kirika <3

.oisyn schreef op maandag 30 maart 2009 @ 23:23:
[...]

Dat doen de generalized parsers dus. Bij ambiguïteiten parsen ze gewoon alle mogelijkheden. Tijdens of na het parsen kun je vervolgens de conflicts resolven adhv een semantische analyse van de rest van het programma.
Ik ben nog niet zo bekend met generalized parsers, maar ik wel o.a. nog Scannerless Generalized-LR Parsing lezen.
.oisyn schreef op maandag 30 maart 2009 @ 23:30:
Kunnen we niet beter gewoon eerst een eigen parser generator maken? :P
Vieze dubbelposter :+

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Parse error at line 1 :Y)

Ik heb de Coco/R parser generator nu zo gehakt dat je tussentijds de parser state op kunt slaan en de error handler wordt vervangen door een dummy hander die eigenlijk alleen bijhoudt of er een error is opgetreden. Aangezien hij een recursive descent parser genereert kun je daarna gewoon de functie aanroepen van de non-terminal die je wilt parsen, zodat je daarna kunt checken of het gelukt is. Dit geheel kun je weer gebruiken in een resolve predicate zodat ik nu goed uit kan vinden of de reeks tokens die komen gaan te parsen zijn als een cast expression. Omslachtig (vooral omdat er nu eigenlijk dubbel geparsed wordt, eerst om te kijken of het lukt, zo ja, het nog een keer doen voor het eggie), maar het werkt wel :)

M'n grammatica ziet er dan alsvolgt uit (dit is nog een heel erg simpele WIP, hij doet alleen binary en unary '+', haakjes en casts, maar het was dan ook vooral om uit te zoeken hoe ik het moest gaan resolven)

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// wat parser support code
bool IsCastExpression()
{
    TryParse tryer(this);
    CastExpression();
    return tryer;
}

// in de grammer definition
    Expression
        = AddExpression
        .
        
    AddExpression
        = AddTerm { "+" AddTerm }
        .
    
    AddTerm
        = "+" AddTerm
        | CastTerm
        .
        
    CastExpression
        = "(" Type ")" CastTerm
        .
        
    CastTerm
        = IF(IsCastExpression()) CastExpression
        | "(" Expression ")"
        | Literal
        .
        
    Literal
        = ident
        | number
        | string
        .

Ter info, Coco/R rebruikt een EBNF notatie waarbij [A] staat voor een optionele A en {A} voor 0 of meer A's

.edit: dit klopt nog niet helemaal, nu werkt (a)(b)c niet (een dubbele cast)
.edit2: zo, dit klopt meer. Let niet meer op m'n naamgeving trouwens ;)

[ Voor 113% gewijzigd door .oisyn op 31-03-2009 02:59 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
RayNbow schreef op maandag 30 maart 2009 @ 23:55:
[...]

Ik ben nog niet zo bekend met generalized parsers, maar ik wel o.a. nog Scannerless Generalized-LR Parsing lezen.
Kijk eens een keertje naar ASF+SDF. ;)

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 20:52

RayNbow

Kirika <3

Grijze Vos schreef op dinsdag 31 maart 2009 @ 01:26:
[...]


Kijk eens een keertje naar ASF+SDF. ;)
Ik heb een klein beetje naar SDF gekeken, maar dat was omdat ik bezig was met Stratego/XT voor een practicum Program Transformation & Generation. :)

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • Alex
  • Registratie: Juli 2001
  • Laatst online: 20-08 21:38
Wat ik wel grappig vind aan dit topic is dat het lijkt alsof er aan het grotere probleem voorbij wordt gegaan:
Waarom een nieuwe taal? En als je die vraag al beantwoord, welke paradigm past dan het beste?
Het probleem bij hedendaagse talen en VMs is volgens mij namelijk niet de feature-set. Als ik kijk naar Java, PHP en C# dan zie ik een zeer rijke set aan functionaliteit die uitgebreid worden met libraries. Hetzelfde geldt voor Ruby en Python(om maar even over te stappen naar Dynamic typing).
Het probleem waar hedendaagse language designers mee lijken te zitten lijkt toch echt hoe je uit te drukken: imperatief of declaratief en hoe blijf je productief? Daarbij: hoe ga je deze combi vertalen naar iets wat schaalbaar is? Je wilt immers niet in de age of paralellism blijven nadenken over de exacte hardware mapping van één specifieke thread.

Persoonlijk zie ik veel in een combinatie tussen een imperatieve definitie taal voor objecten en een declaratieve manier van het code schrijven(de logic).
Ik denk dat de gedachtengang belangrijker is dan welk parsing algoritme dan ook.

Deze post is bestemd voor hen die een tegenwoordige tijd kunnen onderscheiden van een toekomstige halfvoorwaardelijke bepaalde subinverte plagiale aanvoegend intentioneel verleden tijd.
- Giphart


Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 20:52

RayNbow

Kirika <3

Alex schreef op dinsdag 31 maart 2009 @ 10:03:
Ik denk dat de gedachtengang belangrijker is dan welk parsing algoritme dan ook.
Maar er kleeft wel een nadeel aan grammatica's als LL en LALR: ze zijn namelijk niet gesloten onder compositie.

SGLR grammatica's daarentegen zijn wel gesloten onder compositie. Dit is handig als je andere talen wilt embedden in een bestaande taal, bijv. SWUL in Java.

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • Alex
  • Registratie: Juli 2001
  • Laatst online: 20-08 21:38
RayNbow schreef op dinsdag 31 maart 2009 @ 10:46:
[...]

Maar er kleeft wel een nadeel aan grammatica's als LL en LALR: ze zijn namelijk niet gesloten onder compositie.

SGLR grammatica's daarentegen zijn wel gesloten onder compositie. Dit is handig als je andere talen wilt embedden in een bestaande taal, bijv. SWUL in Java.
Je schetst hier precies wat ik niet uitdrukte ;).
Als je voorbij deze globale gedacht bent, heb je de technische requirements voor je parsing algoritme.

Deze post is bestemd voor hen die een tegenwoordige tijd kunnen onderscheiden van een toekomstige halfvoorwaardelijke bepaalde subinverte plagiale aanvoegend intentioneel verleden tijd.
- Giphart


Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Heb je het begin van dit afgeplitste topic wel gelezen :?

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • avandel
  • Registratie: Juli 2006
  • Laatst online: 25-02 13:43
Waarom gaan we niet met z'n allen in afkortingen communiceren? Leest zo lekker weg: IMHO eh, google.... i.m.h.o. ..... oh ja, in my humble opinion, en dan heb je uiteraard ook nog IMNSHO..... wie bedenkt dat toch... AFAIK..???? A- wat?? ach, weer zo een...
Waar is die vent die programmeren wil, het wiel opnieuw wilt uitvinden? Laat hem of haar in afkortingen programmeren, kijken hoe snel ze gek worden... >:)

Tja, een beetje boos ben ik wel, we hebben toch allemaal netjes leren lezen en schrijven op school? Kijk dan alsjeblieft iets verder, als je een afkorting gebruikt, zet dan tenminste 1 keer de betekenis neer, dat leest verdomde makkelijker.
En nee, ik ben er niet op tegen, het gebruik ervan, maar meer de laksheid die op fora's wordt gehandhaaft en het gebrek aan netjes Nederlands te schrijven of het nalezen ervan. Er worden veel typ- en spelfouten gemaakt, laten we dan ook niet nog eens beginnen met afkortingen te kust en te keur te gebruiken. We hebben het al moeilijk genoeg!

Acties:
  • 0 Henk 'm!

  • Alex
  • Registratie: Juli 2001
  • Laatst online: 20-08 21:38
BtM909 schreef op dinsdag 31 maart 2009 @ 11:10:
Heb je het begin van dit afgeplitste topic wel gelezen :?
Ja en daar haal ik wel een 2 aanleidingen uit:
- Leerdoel VM programmeren
- Taal PHP heeft wat beperkingen
Mag ik dit nihil vinden om nog direct met een nieuwe taal te komen?

Deze post is bestemd voor hen die een tegenwoordige tijd kunnen onderscheiden van een toekomstige halfvoorwaardelijke bepaalde subinverte plagiale aanvoegend intentioneel verleden tijd.
- Giphart


Acties:
  • 0 Henk 'm!

Verwijderd

Waar heb je het over?

[ Voor 72% gewijzigd door Verwijderd op 31-03-2009 11:44 ]


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Alex schreef op dinsdag 31 maart 2009 @ 10:03:
Wat ik wel grappig vind aan dit topic is dat het lijkt alsof er aan het grotere probleem voorbij wordt gegaan:
Waarom een nieuwe taal? En als je die vraag al beantwoord, welke paradigm past dan het beste?
...
Eens :) Een nieuwe taal zou impliciet parallel moeten zijn met oog op de volgende generatie hardware. Hoewel dat natuurlijk geen nieuw concept is, want daar is al behoorlijk wat onderzoek naar gedaan en er bestaan ook al een aantal van dat soort talen. Intel komt nu al met de "parallel studio", nvidia en amd etc met OpenCL; keer op keer als ik bij conferenties ben hoor ik het: parallel is de toekomst, bereid je er op voor, of je nou wilt of niet, het komt eraan. Als een algoritme niet schaalt naar meerdere processoren dan is het niet relevant. Dat gaat ook voor talen gebeuren. Handmatig parallel programmeren is te moeilijk. Dat is bij uitstek iets dat een compiler/taal op zou moeten kunnen lossen. Ik zou dus niet blind functionaliteit toe gaan voegen aan een nieuwe taal, maar eerst een kern opzetten en dan bij elke nieuwe functionaliteit vragen of het past bij het ontwerp, en of het wel echt nuttig is.

(ik weet ook niet waar EBNF voor staat, "uh-feek" ;) iets van extended blahblah normal form ;) Weet wel wat het is hehe )

[ Voor 4% gewijzigd door Zoijar op 31-03-2009 13:01 ]


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
avandel schreef op dinsdag 31 maart 2009 @ 11:24:
Tja, een beetje boos ben ik wel, we hebben toch allemaal netjes leren lezen en schrijven op school? Kijk dan alsjeblieft iets verder, als je een afkorting gebruikt, zet dan tenminste 1 keer de betekenis neer, dat leest verdomde makkelijker.
Wat doe je in een topic als dit als je termen als EBNF, LL, LALR, SGLR niet kent? En wie kent in godsnaam standaard afkortingen als imho en afaik niet? Serieus, onder welke steen heb jij gelegen?

Over zeuren gesproken, ik weet bijna zeker dat Word gaat miepen over "En nee, ik ben er niet op tegen, het gebruik ervan, maar meer de laksheid ...". Iets in de trant van "Fragment, consider revising".

[ Voor 18% gewijzigd door Grijze Vos op 31-03-2009 12:40 ]

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
avandel schreef op dinsdag 31 maart 2009 @ 11:24:
Kijk dan alsjeblieft iets verder, als je een afkorting gebruikt, zet dan tenminste 1 keer de betekenis neer, dat leest verdomde makkelijker.
Elke keer 1 keer de betekenis erbij zetten terwijl vrijwel iedereen hier op het forum, behalve jij blijkbaar, weet wat ermee bedoeld wordt? Afkortingen zijn juist handig. Het verminderd ruis zodat je je meer kunt concentreren op de daadwerkelijke inhoud.

En wat de hier gebezigde wetenschappelijke termen betreft, het is niet dat als we het over extended Backus-Naur form hebben dat je dan wel ineens snapt wat ermee bedoelt wordt. En degenen die het wel snappen kennen de afkorting ook. Compleet nutteloos om dat helemaal uit te typen dus.

Dus, samenvattend, IIRC kent zo'n beetje elke GoTer wel al die afkortingen en AFAIK heeft zelden daar iemand problemen mee, dus IMHO ben je gewoon een beetje aan het zuren, ITT de anderen in de topic die IIG wel een relevante bijdrage leveren DMV constructieve posts MBV afkortingen ICM bekende termen :Y)

@hieronder: shut up, I'm trying to make a point here :P

[ Voor 4% gewijzigd door .oisyn op 31-03-2009 14:04 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

.oisyn schreef op dinsdag 31 maart 2009 @ 13:33:
[...]

Dus, samenvattend, IIRC kent zo'n beetje elke GoTer wel al die afkortingen en AFAIK heeft zelden daar iemand problemen mee, dus IMHO ben je gewoon een beetje aan het zuren, ITT de anderen in de topic die IIG wel een relevante bijdrage leveren DMV constructieve posts MBV afkortingen ICM bekende termen :Y)
Moeten dergelijke afkortingen niet met kleine letters? :>

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Ik kom in de problemen met m'n tuples

code:
1
2
var a = <1, 2, 3>;
var b = <1, 2, 3 > 5>; // en nu?


Ik kan natuurlijk voor een andere syntax gaan, zoals [[a,b]] of <:a,b:> of (.a,b.) (ik noem maar wat). De mogelijkheden zijn eindeloos :P. Ik heb denk ik niet zo'n zin om heel moeilijk te gaan doen door te kijken of een > een groter-dan is of een einde-tuple. Momenteel verslikt de parser zich zelfs over <1, 2, 3> omdat hij bij de laatste 3 wil parsen als '3 groter-dan ERROR'

.edit: hmm, ik kan denk het denk ik wel zo krijgen dat een groter-dan nooit die betekenis heeft binnen een tuple, tenzij er haakjes om die expressie staan. <1, 2, 3 > 5> is dus een parse error, dan moet je <1, 2, (3 > 5)> gebruiken.

[ Voor 19% gewijzigd door .oisyn op 31-03-2009 18:32 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

.oisyn schreef op dinsdag 31 maart 2009 @ 18:28:
Ik kom in de problemen met m'n tuples

code:
1
2
var a = <1, 2, 3>;
var b = <1, 2, 3 > 5>; // en nu?


Ik kan natuurlijk voor een andere syntax gaan, zoals [[a,b]] of <:a,b:> of (.a,b.) (ik noem maar wat). De mogelijkheden zijn eindeloos :P. Ik heb denk ik niet zo'n zin om heel moeilijk te gaan doen door te kijken of een > een groter-dan is of een einde-tuple. Momenteel verslikt de parser zich zelfs over <1, 2, 3> omdat hij bij de laatste 3 wil parsen als '3 groter-dan ERROR'

.edit: hmm, ik kan denk het denk ik wel zo krijgen dat een groter-dan nooit die betekenis heeft binnen een tuple, tenzij er haakjes om die expressie staan. <1, 2, 3 > 5> is dus een parse error, dan moet je <1, 2, (3 > 5)> gebruiken.
Lijkt me ook duidelijker! ik vind <1, 2, 3 > 5> niet echt leesbaar. Ik moet twee keer kijken om 't goed te begrijpen. <1, 2, 3, (3 > 5) > vind ik veel duidelijker.

Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 20:52

RayNbow

Kirika <3

Zoijar schreef op dinsdag 31 maart 2009 @ 12:32:
Handmatig parallel programmeren is te moeilijk. Dat is bij uitstek iets dat een compiler/taal op zou moeten kunnen lossen.
Zoiets is een best lastige taak voor de compiler(bouwer). Welke informatie heeft de compiler nodig om te kunnen bepalen dat iets in parallel kan worden gedraaid? Welke informatie heeft de compiler nodig om te bepalen of het waard is om iets te parallelliseren? Met welke evaluatiestrategie?

* RayNbow kan het nu niet laten om een sprongetje naar Haskell te maken... O-)

In Haskell heeft de compiler informatie of een functie puur of side effects heeft. Deze informatie is namelijk beschikbaar in de types. Een functie met arbitraire side effects heeft IO a als result type.**

Verder kan je in Haskell met de primitieve par en pseq combinatoren pure code annoteren om te bepalen wat er eventueel in parallel moet worden uitgevoerd. Met deze combinatoren kun je verder uitgebreidere evaluatiestrategieen creeren, bijvoorbeeld:
Haskell:
1
2
3
someList `using` parListChunk 64 rnf
-- knip de lijst in stukjes van 64 lang en evalueer de chunks in parallel
-- (rnf = reduce normal form)


** Waarschuwing, het is mogelijk om de Haskell compiler/typechecker te bedonderen...
Afbeeldingslocatie: http://www.scientia.demon.nl/UnsafePerformIO.png
Gebruik op eigen risico :+
.oisyn schreef op dinsdag 31 maart 2009 @ 18:28:
Ik kom in de problemen met m'n tuples

code:
1
2
var a = <1, 2, 3>;
var b = <1, 2, 3 > 5>; // en nu?


Ik kan natuurlijk voor een andere syntax gaan, zoals [[a,b]] of <:a,b:> of (.a,b.) (ik noem maar wat).
Heb je ook overwogen om (a,b,c) te gebruiken voor de tupelsyntax?

[ Voor 10% gewijzigd door RayNbow op 31-03-2009 20:00 ]

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Ja - in een taal als C++ betekent dat namelijk evalueer in volgorde a, b en c, en retourneer c.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Volgende probleem: m'n function reference syntax.
code:
1
2
function(int):int a; // een functie die int returnt
function(int):int[] b; // een functie die int[] returnt, of een array van functies die int returnen?


Ik kan natuurlijk met haakjes gaan werken, dan is bovenstaande b een functie die int[] returnt, en is een array van functies die int returnen zo:
code:
1
(function(int):int)[] a;

Het punt is alleen dat m'n grammar dan echt heel moeilijk te parsen wordt op verschillende punten. Met name: (a)b. Is dat nou een variabele-definitie, of een cast-expression.

Ik neig ernaar om het return-type naar het midden te verplaatsen, dus zo:
code:
1
2
3
function:int(int) a;
function:int[](int) b; // b returnt int[]
function:int(int)[] c; // c is array, c[0] returnt int


De vraag is dan, hoe wordt een named function definition dan:
code:
1
2
3
4
5
6
7
8
9
10
11
// #1
function add : int (int a, int b)
{
    return a + b;
}

// #2
function:int add(int a, int b)
{
    return a + b;
}

Welke vinden jullie mooier?

.edit: ik denk dat ik zelf #2 mooier vindt. Als ik een spatie toevoeg lijkt het ook veel meer op een C-style functie definitie waar toevallig "function:" voor staat.
code:
1
function: int add(int a, int b) { }

Daarentegen is #1 makkelijker te parsen.

[ Voor 10% gewijzigd door .oisyn op 01-04-2009 00:09 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • JeromeB
  • Registratie: September 2003
  • Laatst online: 14-08 21:56

JeromeB

woei

#3
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function add(a:int,b:int):int
{
   return a + b
}

addFunc:int->int = add

function int_array():[int]
{
}

function func_array():[int->int]
{
}



Misschien is het trouwens ook handig om een soort simpel generics/template-systeempje intebouwen, hoewel dat misschien het dynamic-typing wat in de weg zit:

voorbeeldje:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
fn max[T](a:T,b:T):T
{
  if (a<b) return b

  return a
}

fn max[T](a:T,b:T,...):T
{
  return max(max(a,b),...)
}

output("max: ",max(4,5,3,8,3)); // 8


.oisyn, waarom verander je niet gewoon die ideeen voor casting-syntax. Ik vind die haakjes eigenlijk gigantisch irritant.

[ Voor 104% gewijzigd door JeromeB op 01-04-2009 01:04 ]

PC load letter? What the fuck does that mean?


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Ik vind een functiestijl cast sowieso lekkerder werken, bv static_cast<int>(x), omdat de haken dan om het stuk dat je wilt casten heen staan. Anders is het altijd zo onduidelijk hoe hard de cast bind... (float) 3 / 4, is dat 0.0 of is dat 0.75 ? Alleen is het een beetje veel typen soms. Misschien iets als: <float>(3) / 4 ?

Acties:
  • 0 Henk 'm!

  • JeromeB
  • Registratie: September 2003
  • Laatst online: 14-08 21:56

JeromeB

woei

Inderdaad, dat vind ik in C++ bijvoorbeeld een stuk duidelijker dan de C-style-casts.

Wat is er trouwen mis met constructor-style casts? value:float = float(3)/4

PC load letter? What the fuck does that mean?


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Hoe maak je hieruit op dat addFunc 2 parameters heeft?
code:
1
function int_array():[int]
[type] gaat niet werken, die gebruik ik al voor array literals: a = [1, 2, 3, 4]. Daarnaast, hoe had jij hashmaps voorgesteld? Ik definieer die nu als int[string] (een hashmap van int values met string keys)
.oisyn, waarom verander je niet gewoon die ideeen voor casting-syntax. Ik vind die haakjes eigenlijk gigantisch irritant.
Kan best, maar het lost vrij weinig op als je dat soms dacht :). Verder: a(b), Is dat een functie aanroep, of een cast (en doet dat er eigenlijk toe?).

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • JeromeB
  • Registratie: September 2003
  • Laatst online: 14-08 21:56

JeromeB

woei

.oisyn schreef op woensdag 01 april 2009 @ 02:11:
[...]

Hoe maak je hieruit op dat addFunc 2 parameters heeft?
Excuses, dat had natuurlijk addFunc:int->int->int moeten zijn. Dit zie je ook veel in ML-afgeleide-talen.
.oisyn schreef op woensdag 01 april 2009 @ 02:11:
[...]

[type] gaat niet werken, die gebruik ik al voor array literals: a = [1, 2, 3, 4]. Daarnaast, hoe had jij hashmaps voorgesteld? Ik definieer die nu als int[string] (een hashmap van int values met string keys)
Misschien een domme vraag, maar waarom gaat dat niet werken? Ondanks dat je de [] ook gebruikt voor array-literals zie ik niet waarom je die [] niet zou kunnen gebruiken binnen je type-declaratie.

Over hashmaps heb ik verder nog niet nagedacht.
.oisyn schreef op woensdag 01 april 2009 @ 02:11:
[...]

Kan best, maar het lost vrij weinig op als je dat soms dacht :). Verder: a(b), Is dat een functie aanroep, of een cast (en doet dat er eigenlijk toe?).
Geen idee, hoe doet men dat in C++?

PC load letter? What the fuck does that mean?


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
JeromeB schreef op woensdag 01 april 2009 @ 03:50:
Ondanks dat je de [] ook gebruikt voor array-literals zie ik niet waarom je die [] niet zou kunnen gebruiken binnen je type-declaratie.
Omdat ik C-style variabel definities gebruik
code:
1
2
3
4
int a;
[int] b;
[mytype] c;
[1]; // oeps, array literal

Het lost dus geen problemen op, het vervangt ze alleen door nieuwe :). Dan kun je zeggen: dan moeten je var defs zo zijn: a : int, maar dat conflicteert weer met de 'foreach'
code:
1
2
for (i : [1, 2, 3])
    // ...

Dus dan moet ik die ook gaan aanpassen.
Geen idee, hoe doet men dat in C++?
C++ is geen goede indicatie omdat je tijdens het parsen al kunt weten wat types zijn en wat niet. En voor de situatie waarin je dat niet kunt weten, zoals in templates, moet je dan ook het keyword typename gebruiken:
C++:
1
2
3
4
5
template<class T> void foo()
{
    T::bar(34); // nested type, or static function? Compiler assumes function
    typename T::bar(34); // now it's a type
}

[ Voor 45% gewijzigd door .oisyn op 01-04-2009 10:53 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

.oisyn schreef op woensdag 01 april 2009 @ 02:11:
Kan best, maar het lost vrij weinig op als je dat soms dacht :). Verder: a(b), Is dat een functie aanroep, of een cast (en doet dat er eigenlijk toe?).
Volgens mij niet. Een cast is gewoon een functie van het ene type naar het andere. Maar sommige casts moeten build-in zijn omdat de taal het soms niet op een andere manier kan. Dan nog is het gewoon een build-in functie. In C++ kan je alle pointer casts zo schrijven (uit mn hoofd...):

template <typename To, typename From>
To cast(From x) {
union {To to, From from} tmp;
tmp.from = x;
return tmp.to;
}

Constructor cast werkt volgens mij ook prima. C# doet dat toch?

Ik weet niet of je van plan was pointers te ondersteunen, maar klassiek kan dat niet als functie of ctor stijl cast omdat de * niet in een normale identifier voor mag komen.

[ Voor 10% gewijzigd door Zoijar op 01-04-2009 11:16 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Geen pointers. Overigens heb ik ook de "as" operator geleend uit C# (een dynamic_cast op pointer niveau zeg maar)

code:
1
MyClass a = b as MyClass;

Dat is heerlijk om te parsen. Voor harde casts (dynamic_cast met reference) zou ik ook iets als dit kunnen doen:
code:
1
2
3
MyClass a = b -> MyClass
// of
MyClass a = b cast MyClass

Ik heb nog even na zitten denken aan die function-style casts, en het punt is dat ik die dingen dan moet gaan zitten resolven in m'n VM, en dus niet puur aan de AST alleen kan zien of iets een cast is of niet.

Het voordeel van een cast keyword is bovendien dat je erop kunt zoeken :)

Het is trouwens built-in ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
ik vind het gebruik van het cast keyword wel een mooie oplossing. De -> notatie zou ook wel kunnen, maar dat levert denk eerder verwarring op.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

.oisyn schreef op woensdag 01 april 2009 @ 12:35:
Geen pointers. Overigens heb ik ook de "as" operator geleend uit C# (een dynamic_cast op pointer niveau zeg maar)

code:
1
MyClass a = b as MyClass;

Dat is heerlijk om te parsen. Voor harde casts (dynamic_cast met reference) zou ik ook iets als dit kunnen doen:
code:
1
2
3
MyClass a = b -> MyClass
// of
MyClass a = b cast MyClass

Ik heb nog even na zitten denken aan die function-style casts, en het punt is dat ik die dingen dan moet gaan zitten resolven in m'n VM, en dus niet puur aan de AST alleen kan zien of iets een cast is of niet.

Het voordeel van een cast keyword is bovendien dat je erop kunt zoeken :)
Ok, denk er maar over na. Alles behalve die ronde haken C cast ;)
Het is trouwens built-in ;)
Ja... :X Dat doe ik dus altijd fout, op de een of andere manier krijg ik dat er niet in. Al die d/t werkwoorden trouwens.

Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Om het nog moeilijker te maken:
code:
1
MyClass a = dyncast(MyClass, b);

Wat Zoijar aanhaalt is iets waar ik me ook aan stoor: wat is de scope van een C-style cast? Daarom zijn C++ casts ook zoveel cleaner, behalve hun lange naam.

Of nog een voorstel:
code:
1
MyClass a = MyClass.From(b)

Deze kent wel wat obvious nadelen, maar ik wou jullie hem toch niet onthouden...

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Nu online

alienfruit

the alien you never expected

En vervolgens heb je dan ook ?

code:
1
if a is MyClass {}

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Uiteraard, maar dan met haakjes eromheen zoals vaker het geval is bij if statements ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Zo, ik heb een aantal wijzigingen doorgevoerd. Tuples zijn nu met normale haakjes, de cast gebeurt nu met het cast keyword zoals boven aangegeven, en de functie syntax is nu fn foo(int a, float b) -> (int) { }
Met dank aan JeromeB voor het fn keyword, ik zat er idd over te denken om "function" in te korten naar "f" of "func" oid, maar "fn" vind ik wel een goede :)

Het volgende parset nu prima
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
namespace ns
{
    class MyClass : MyInterface
    {
        private static int myVar = 34;

        public fn foo() -> (int, float, string, fn(int)->(int))
        {
            print("hi there");
            int[] i = new int[34];
            try
            {
                for (int j : [1, 2, 3, 4])
                    alert(j * 3);
                throw i[34].toString();
            }
            catch(Exception e)
            {
                print("Caught exception");
            }
            finally
            {
                something();
            }
            return (1, 2 cast float, "hoi", fn(int a)->(int){ return a + 4; });
        }
    }
}

[ Voor 68% gewijzigd door .oisyn op 01-04-2009 18:20 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

.oisyn schreef op woensdag 01 april 2009 @ 18:15:
Met dank aan JeromeB voor het fn keyword, ik zat er idd over te denken om "function" in te korten naar "f" of "func" oid, maar "fn" vind ik wel een goede :)

Het volgende parset nu prima
code:
1
public fn foo() -> (int, float, string, fn(int)->(int))
Heb je het keyword "fn" echt nodig?
<access-specifier> <identifier> (<arguments>) -> (<return-types>)
lijkt me uniek. Lijkt me ook te werken als argument type
(<arguments>) -> (<return types>)
En als lambda functie lijkt me ook uniek parseable:
(<arguments>) -> (<return types>) { <implementatie> }

Het parsed waarschijnlijk wel een stuk makkelijker :)

[ Voor 15% gewijzigd door MLM op 01-04-2009 19:22 ]

-niks-


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
De argumenten komen na de identifier, na de -> komen de return-values :). Maar op die plek is het idd niet meteen nodig, maar voor lambda's midden in code zeker wel. En houdt er rekening mee dat het een free-form taal is, in de global scope kunnen dus ook gewone statements staan (en dan heb je nog function definitions *in* functies). En dan wordt het ook vrij lastig om een functie-definitie te herkennen.

[ Voor 7% gewijzigd door .oisyn op 01-04-2009 19:20 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

.oisyn schreef op woensdag 01 april 2009 @ 19:20:
De argumenten komen na de identifier, na de -> komen de return-values :). Maar op die plek is het idd niet meteen nodig, maar voor lambda's midden in code zeker wel. En houdt er rekening mee dat het een free-form taal is, in de global scope kunnen dus ook gewone statements staan (en dan heb je nog function definitions *in* functies). En dan wordt het ook vrij lastig om een functie-definitie te herkennen.
Mja, was al aant editten, soz :)

Waar gebruik je nog meer pijltjes voor dan?
Ik heb een hekel aan overbodige keywords in welke taal dan ook.
Aan de andere kant, misschien word het wel onleesbaarder zonder dat keyword...

[ Voor 10% gewijzigd door MLM op 01-04-2009 19:24 ]

-niks-


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

feature request:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
active class Someclass
{
  public fn foo(int a) -> (int)
  {
    return a*2;
  }
  protected fn iteration() -> (int)
  {
     alert(foo(3));
     return 10; // time to wait in ms before calling iteration() again
  }
};

SomeClass global;

fn runA() -> ()
{
  alert(global.foo(10));
}

thread a = new thread(runA);
a.start();


iteration is niet zozeer mijn requirement, maar is zeker een mooie addition: als ze er is, wordt ze telkens uitgevoerd tot de class gedestruct wordt. Eventueel kun je nog een initialize() en cleanup() erbij gooien die je kan overriden om de functionaliteit in te vullen. Anderzijds kun je de constructor en de destructor deze functionaliteit laten vervullen. Deze 3 (1?) functies zijn optioneel, in de basis moeten ze niet aanwezig zijn,
in dat geval doet de de thread niet meer dan gedispatchete-calls uitvoeren

Waar het vooral om draait is dat een active class een thread associeert met het object (of put uit een threadpool?), die thread runt alle code van de class (incl constructor/desctructor) en alle externe function calls worden automatisch gedispatched op die thread.

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Die 'active' class me een vrij nutteloze taalfeature, aangezien het ook prima met een library opgelost kan worden. Dan wordt het zoiets:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Someclass
{
  private Timer timer;
  public fn Someclass()
  {
     timer = new Timer(10, iteration);
  }

  protected fn iteration()
  {
     alert(foo(3));
  }
}

(Let erop dat een functie die niets returnt ook geen ->() hoeft te hebben ;))

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Zoals ik zelf al aangaf is die iteration() niet zozeer de kern van de zaak.

Het gaat hem over het dispatchen van calls vanuit externe threads naar een andere thread. Dit is in veel talen nu een probleem. Je moet maar eens in C++ een eenvoudig mechanisme te verzinnen waar:
C++:
1
2
3
4
5
6
7
class X; // thread A is owner

// thread A
x.foo();

// thread B
x.foo()

Er automatisch voor zorgt dat de x.foo() vanuit A een rechtstreekse function call is en x.foo() vanuit B een gedispatchete function call. Daar heb je gewoon language support voor nodig. boost::bind of std::bind1st of std::bind2nd kunnen je misschien een klein beetje helpen, maar die gegenereerde types zijn zo complex dat je ervan afziet om het te gaan gebruiken.

In C# heb ik zoiets met delegates, wat al een stuk lekkerder werkt, maar toch moet ik nog steeds generic delegates en reflection gebruiken om te raken waar ik wil raken.

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Wat dan als thread B die call doet en thread A is heel wat anders aan het doen?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Dan blokkeert threadB netjes tot A die call kan afhandelen.

Voor je erover begint: er zullen vast wel manieren zijn om deadlocks te voorkomen tussen 2 active classes.
Zoals bijvoorbeeld ipv te blokkeren, gedispatchete calls naar de eigen thread te gaan afhandelen en na elk van die calls pollen of de operatie gedaan is. Dit heeft natuurlijk wel enkele nadelen, nl dat de atomiciteit van een operatie verbroken wordt bij elke call naar een andere active class.

anderzijds kun je met een async keyword ala
code:
1
2
3
fn asynchandler(int result)

async x.foo() asynchandler

er voor zorgen dat de call asynchroon uitgevoerd wordt. Welke syntax je eraan geeft is natuurlijk bijzaak hier.
Je kan er dan bvb ook statisch voor zorgen dat er geen synchrone call loops zijn tussen active classes. Doet de gebruiker dit toch, dan klaagt de compiler.

[ Voor 9% gewijzigd door H!GHGuY op 03-04-2009 19:06 ]

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
H!GHGuY schreef op vrijdag 03 april 2009 @ 19:05:
Dan blokkeert threadB netjes tot A die call kan afhandelen.
Wanneer kan A die call afhandelen dan? Ik bedoel, is het niet gewoon een thread die ook code runt? Of wil je dat ie een soort van (handmatige) message loop doet, wachtend op commando's van andere threads.
anderzijds kun je met een async keyword ala
code:
1
2
3
fn asynchandler(int result)

async x.foo() asynchandler

er voor zorgen dat de call asynchroon uitgevoerd wordt. Welke syntax je eraan geeft is natuurlijk bijzaak hier.
Je kan er dan bvb ook statisch voor zorgen dat er geen synchrone call loops zijn tussen active classes. Doet de gebruiker dit toch, dan klaagt de compiler.
Klinkt een beetja als C++0x's futures (let wel, dit is niet de final proposal, maar wel het beste artikel dat ik kon vinden met de meeste achtergrond-informatie, in plaats van wat droge bewoording uit de C++ standaard :))

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

.oisyn schreef op vrijdag 03 april 2009 @ 23:15:
Wanneer kan A die call afhandelen dan? Ik bedoel, is het niet gewoon een thread die ook code runt? Of wil je dat ie een soort van (handmatige) message loop doet, wachtend op commando's van andere threads.
Juist.
En eventueel kun je die thread nog exposen dmv die iteration call.
Klinkt een beetja als C++0x's futures (let wel, dit is niet de final proposal, maar wel het beste artikel dat ik kon vinden met de meeste achtergrond-informatie, in plaats van wat droge bewoording uit de C++ standaard :))
Weeral juist ;)

Het verschil is echter dat je bij futures verdere processing kan doen en op een gegeven moment future<int>.getValue() doet. Bij deze implementatie geef je een handler mee die met het resultaat aangeroepen wordt.
Het gedrag kan je dan ook zo specifieren dat wanneer je 2 active classes hebt en de ene een async call doet naar de andere met een handler uit zijn eigen class:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
active class B
{
  public fn foo() -> (int) { ... }
}
active class A
{
  public fn asynchandler(int)
  {
    // doe iets
  }
  public fn foo()
  {
     async b.foo() asynchandler
  }
}

dat de asynchandler dan ook gedispatchet wordt op de thread van A, want deze wordt opgeroepen vanuit thread B.

Je kan dit vergelijken met het doorbreken van een boost::shared_ptr loop dmv het gebruik van een weak_ptr.
Alleen kan je hier statisch en at compile time bepalen of er geen call-loops zijn tussen active classes.

Een andere, en misschien betere, oplossing is dat wanneer active object B een functie oproept van active object A en er een callback is naar active object B (wat dus een deadlock zou opleveren) je die call gewoon synchroon, zonder dispatching uitvoert. thread B is immers aan het wachten op de call van A en er is dus geen gevaar voor thread-unsafe handelingen.


Mocht je dit in C++ willen uitvoeren dan heb je gewoon language support nodig:
- automatische type-generatie voor het dispatchen van de calls
anders moet je zelf per call een struct/class maken die je kan posten in een msgQ, wat teveel werk is.
- Van veel calls (niet alle) kan je statisch afleiden of je zal moeten dispatchen of als je de functie rechtstreeks kan oproepen. Door een call-graph op te stellen kan je per functie bepalen of ze vanuit 1 of meer threads aangeroepen kunnen worden. Eventueel kun je zelfs verschillende versies van een call laten genereren die dan ook andere calls dispatched of juist rechtstreeks aanroept.
- het wrappen van de echte call in een
code:
1
2
3
4
if (currentThread() == objectAssignedThread)
  direct_call()
else
  dispatch_call()

kan door de compiler gedaan worden, inclusief het effectief dispatchen. Mogelijk wordt de stack van de huidige thread gebruikt door de andere thread, enz.
- Een compiler kan heel veel optimalisatiestappen doen die je met library code niet kan doen.
- Parallellisme uitdrukken vereist 1 of 2 keywords: active en eventueel async.

[ Voor 21% gewijzigd door H!GHGuY op 04-04-2009 11:50 ]

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Je feature request lijkt me te specifiek. Het helpt verder ook niet voor algemene parallellisatie van code - je runt namelijk nog steeds die calls in 1 specifieke thread. Ik zeg niet dat het niet zinnig is, maar het aantal usecases is imho te klein om daar een taal omheen te ontwerpen. Ik zie meer heil in taalsupport voor dingen als transactional memory e.d.

Anyway, even een update over Proton. Ik heb momenteel een parser die van het geheel een abstract syntax tree maakt, met een bijbehorende visitor interface. Next up is semantic checking (en het bouwen van een type library) en daarna bytecode generation :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Was er al sprake geweest van iets van generics of template-achtige constructies?

Wat ik namelijk wel een handige feature zou vinden is een soort generic typing voor exceptions. Wat eigenlijk belachelijk is in heel veel talen, is dat je in de meeste talen voor elk type exception een nieuwe class aan moet maken, alleen maar om daar in een catch onderscheid op te kunnen maken. Logisch, zou je zeggen, want een class is nu eenmaal een type. Maar in heel veel gevallen is de enige reden dat je een nieuwe exception wilt helemaal niet dat die exception zo anders is, maar dat je anders geen manier hebt om in een catch() onderscheid te maken t.o.v. het meer generieke type exception.

Even afgezien van de syntax dacht ik aan zoiets. Oud:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MyException extends Exception {}

class MyMoreSpecificException extends MyException {}

function something () {
   throw new MyMoreSpecificException ("Message");
}

try {
    something();
} catch ( MyMoreSpecificException specific ) {
    // ...
} catch ( MyException generic ) {
    // ...
}


nieuw:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
exception MyException<const string type> {
   const string TYPE_A = "A";
   const string TYPE_B = "B";
}

fn something () {
   throw MyException<MyException.TYPE_A> ( "Message" );
}

try {
   something ();
} catch (MyException<MyException.TYPE_B> specific) {

} catch (MyException generic) {

}
Ik moet toegeven dat ik er niet heel goed over nagedacht heb, maar daar is dit topic voor, toch? ;)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Is 't echt zo'n probleem? Je twee voorbeelden verschillen niet heel veel van elkaar in aantal regels code namelijk :). Maar dat is waarschijnlijk ook omdat je geen constructors in de exceptions hebt gedefinieerd, en volgens mij is dat precies waar het probleem ligt. Het blijft niet bij gewoon een "class B extends A { }" tikken. Maar zou het dan niet een betere oplossing zijn als je het wel daarbij kon laten, en nog steeds B kon constructen met argumenten uit de ctor van A, zonder dat je de ctor van B expliciet moet definieren? :)

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class A
{
    public fn A(string s) { }
}

class B : A
{
}

class C : A
{
    public fn C(int i) { }
}

class D : A
{
    using A;
    public fn D(int i) { }
}

B b = new B("woei");  // ok, B ctor default inherit van A
C c = new C("woei");  // error, de definitie van C(int) hide de ctors van A
D d = new D("woei");  // ok, de ctors van A worden expliciet geinherit door de using declaration

[ Voor 28% gewijzigd door .oisyn op 28-04-2009 18:03 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Het zou inderdaad mooi zijn als constructors default geërfd worden. Al is dat op het moment ook niet zo'n groot probleem met de juiste ontwikkelomgeving, dan worden ze immers automatisch gegenereerd als je dat vraagt.

Maar het komt zo vaak voor dat je constructors 1 op 1 doorlust, dat het geen verkeerde feature zou zijn.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Nou, probleem niet, maar het is op twee manieren eleganter vind ik. Het voorbeeld is misschien niet zo goed, misschien is dit duidelijker:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
fn doQuery() {
    try {
        // do some query
    } catch(SqlException<SqlException.DUPLICATE_KEY> e) {
        // doQuery knows how to fix this one
    }
}

fn runApp() {
    try {
        doQuery();
    } catch(SqlException<SqlException.CONSTRAINT_ERROR> e) {
        // runApp knows how to fix this one
    }
}

try {
    runApp();
} catch(SqlException<SqlException.CONNECTION_ERROR> e) {
    // etc...
}

Je hebt dus geen expliciet nieuw type (class) nodig om alle soorten SQL exceptions afzonderlijk af te kunnen vangen, én je kan je try/catch eenvoudig houden zonder exception te hoeven rethrowen als het generic type bekend is. Als je nagaat hoeveel verschillende soorten SQL errors er zijn, is het begrijpelijk dat er niet zoveel verschillende SQL exceptions zijn, maar het is in heel veel gevallen wel praktisch om te weten wat voor soort sql exception het is. Het gaat me dus niet zozeer om het typen van meer code, want daar ben ik opzich niet zo vies van, maar meer het principe dat je een nieuwe class moet definieren om een exception specifiek af te kunnen vangen, terwijl dat theoretisch met bovenstaand verhaal op te lossen moet zijn.

Misschien is de denkrichting wel verkeerd hoor, maar ik kon me zo voorstellen dat je ueberhaupt al wel ideeën had over generic typing.

Misschien kun je het ook anders oplossen door een catch() een soort boolean expressie te laten evalueren, waarbij catch (Type a) een soort suiker is voor (Exception a, a instanceof Type ? a = (Type)a : false), zodat je iets zou kunnen zeggen in de geest van:
code:
1
2
3
4
5
try {
    //
} catch (SqlException e, e.type == SqlException.DUPLICATE_KEY) {

}

edit:
Bovenstaande komma zou dan een && moeten zijn, denk ik, maar dat even terzijde

Maar dat lijkt me veel lastiger in een grammatica vast te leggen?
Je twee voorbeelden verschillen niet heel veel van elkaar in aantal regels code namelijk :). Maar dat is waarschijnlijk ook omdat je geen constructors in de exceptions hebt gedefinieerd, en volgens mij is dat precies waar het probleem ligt. Het blijft niet bij gewoon een "class B extends A { }" tikken. Maar zou het dan niet een betere oplossing zijn als je het wel daarbij kon laten, en nog steeds B kon constructen met argumenten uit de ctor van A, zonder dat je de ctor van B expliciet moet definieren? :)
Dat vind ik sowieso een goed idee :)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
drm schreef op woensdag 29 april 2009 @ 09:38:
[...]
code:
1
2
3
4
5
try {
    //
} catch (SqlException e, e.type == SqlException.DUPLICATE_KEY) {

}

edit:
Bovenstaande komma zou dan een && moeten zijn, denk ik, maar dat even terzijde

Maar dat lijkt me veel lastiger in een grammatica vast te leggen?
Maar is dat zoveel anders dan gewoon door throwen?
code:
1
2
3
4
5
try{
    //
} catch(SqlException e) {
    if( e.type != SqlException.DUPLICATE_KEY ) throw;
}

Als je met 1 regel code een nieuwe exception kunt maken dan zou ik het overigens gewoon zo doen
code:
1
2
3
4
5
6
7
class DuplicateKeySqlException : SqlException {}

try{
    //
}
catch(DuplicateKeySqlException e) {
}

Dat is net zoveel type werk, en ik vind het er netter uit zien. Je zult toch ergens vast moeten leggen welke exception types er zijn, waarom dan niet in een class definition? Op die manier kun je ook makkelijker meerdere nivo's van exceptions maken. Want hoe wil je het anders doen als je nog een sub-class van DuplicateKeySqlException krijgt?
code:
1
2
3
4
5
6
7
class SpecialDuplicateKeySqlException : DuplicateKeySqlException {}

try{
    //
}
catch(DuplicateKeySqlException e) {
}

Deze vangt een SpecialDuplicateKeySqlException ook op, als je dat in jouw geval ook wilt doen zou SqlException.SPECIAL_DUPLICATE_KEY een child moeten zijn van SqlException.DUPLICATE_KEY. Maar dan ben je het probleem imho alleen aan het verleggen.

[ Voor 23% gewijzigd door Woy op 29-04-2009 09:57 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 12-09 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Woy onderschrijft idd het punt dat ik probeerde te maken. Regels code heb je sowieso nodig - of je nou verschillende classes hebt of verschillende enum waarden oid. En dan lijkt het me met verschillende classes toch duidelijker. En wat als nou blijkt dat je voor SqlException<SqlException.CONNECTION_ERROR> toch wat meer attributen op wilt nemen dan voor de overige SqlException<T>s? Als het een ConnectionErrorSqlException was kun je gemakkelijk de class aanpassen. Nu zul je ervoor moeten kiezen om het of alsnog een aparte class te maken, of elke SqlException<T> die eigenschappen mee te geven.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1 2 Laatste