[alg] aantrekelijke syntax hogere orde fun.

Pagina: 1
Acties:

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Ik schiet nu hard op met een taaltje dat ik nu aan het schrijven ben, maar mijn grootste probleem is eigelijk om de syntax een beetje aantrekkelijk te krijgen.

Vooral de hogere orde functies zit ik op dit moment even mee te knoeien. Op dit moment heb ik het volgende:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function foo():Int
    return 10;

function foo(Int a):Int 
    return 10;
    
function bar<X>(X a):Int
    return 10;  
    
function bar<X>(X a, X b):Int
    return 10;  
    
function blaat():Int
begin
    (Int):Int f1 := function foo(Int)
    (Int):Int f2 := function bar<Int>(Int)
    (Int,Int):Int f3 := function bar<Int>(Int,Int);
    ():Int f4 := function foo();
    Int x := foo();         
    return 10;
end 


Mijn probleem zit hem dus bij krijgen op een handle naar een functie (zie mijn laatste 4 assignments). Het woord function is nodig omdat ik andere een amgibuiteit erin zou krijgen, maar ik kan niet zeggen dat ik hier nou zo blij mee ben. Oja, ik wil graag mijn context vrije grammatica ook context-vrij houden :)

[edit]
En verder moet de grammatica niet de cryptische kant op gaan (helaas). Het moet nog redelijk te lezen zijn.

[edit2]
In dit voorbeeld staan trouwens geen hogere orde functies, maar dat kan dus als volgt:

Java:
1
2
function zinloos((Int):Int f,Int x):Int
      return f(x);

[ Voor 38% gewijzigd door Alarmnummer op 27-04-2003 21:56 ]


  • HunterPro
  • Registratie: Juni 2001
  • Niet online
en nu je vraag? :P

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Ik wil graag weten hoe het in andere (aantrekkelijke niet cryptische) talen gebeurt.

[edit]
en verder sta ik open voor syntax verbeteringen.

[ Voor 27% gewijzigd door Alarmnummer op 27-04-2003 21:53 ]


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Vrijwel elke programmeertaal heeft, semantische gezien, ambiguiteiten. Semantische analyse bepaalt daarbij pas de echte betekenis van bijvoorbeeld typisch identifiers.

Het is wel aardig om eens na te denken over de vraag wanneer een context-vrije grammatica nu eigenlijk niet meer context-vrij is: welk niveau van informatie verlang van je van een context vrije grammatica? Vele talen kiezen ervoor om identifiers wel ambigue te laten zijn, sommige talen in wat ergere mate dan andere (Java is bijvoorbeeld dramatisch).

Het is natuurlijk ideaal als je al heel veel informatie over de betekenis van constructies hebt na het parsen. Als je de betekenis van alle constructies puur op basis van de syntax wilt achterhalen, heb je gewoon veel syntax nodig ;) . Je moet dus steeds een keuze maken hoever je wilt gaan.

Verder is het beperken van type aanduidingen een nobel streven imho. In een functionele taal is het een ware hel als je van elke wisse-wasje percee het type op moet geven. Type inferentie kan dat uiteraard oplossen, waarbij je sterke (en zelfs statische) typering niet hoeft te verliezen.

In Haskell is de binding van argumenten aan identifiers gescheiden van een type specificatie.
code:
1
2
function foo():Int
    return 10;


Zou dan worden:
code:
1
2
3
4
foo :: Int

function foo()
    return 10;


en:
code:
1
2
function foo(Int a):Int 
    return 10;

wordt
code:
1
2
3
foo :: Int -> Int
function foo(a)
    return 10;


Functie argumenten (voor hogere orde functies dus) worden gewoon aangegeven met (Int -> Int). Door de scheiding van type specificatie en binding aan een identifier blijft dit duidelijk.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
mbravenboer schreef op 27 april 2003 @ 22:06:
Functie argumenten (voor hogere orde functies dus) worden gewoon aangegeven met (Int -> Int). Door de scheiding van type specificatie en binding aan een identifier blijft dit duidelijk.
Ik weet het *is beetje thuis in Haskell* Maar ik wou het dichter bij Pascal laten komen omdat dat over het algemeen wat leesbaarder is. Ik heb er persoonlijk geen problemen mee, maar de tekst moet ook nog redelijk leesbaar zijn voor iemand die minder hierin thuis is.

En type-inference staat ergens helemaal onderaan mijn lijstje. Voorlopig zal je alles zelf moeten parametriseren omdat ik eerlijk gezegd nog meer dan genoeg andere (belangrijkere) zaken te doen heb.

Volledige type-inference staat zelfs nog lager op mijn lijstje, maar type-inference voor functie-type-argumenten gaat nog wel een keer gebeuren.

[edit]
zo`n slecht idee is het misschien nog niet eens, om de functie signature en de bindings van elkaar te scheiden.

[ Voor 18% gewijzigd door Alarmnummer op 27-04-2003 22:27 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Op dit moment staat het afronden van een basis-systeem op de 1e plaats. En daarna ga ik beginnen met de koppeling naar EJB. Ik wil in ieder geval genoeg met mijn systeem kunnen, om ook wat simpele zaken met EJB te kunnen doen.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Wat ik trouwens ook nog kan doen is als er geen ambiguiteiten voor functie selectie is, de volledige functie signature achterwege laten.

(Float):Float f = function sin;

ipv

(Float):Float f = function sin(Float);

Ik denk dat dit voor 99% van de gevallen al een hele mooie oplossing is.

[edit]
En function heb ik nu vervangen door get_function


(Float):Float f = get_function sin;

[ Voor 25% gewijzigd door Alarmnummer op 27-04-2003 22:41 ]


  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
Hmm, ik ben helemaal thuis in Pascal, en een klein beetje in C/C++/PHP/Java, maar uit een regel als
code:
1
(Int):Int f1 := function foo(Int)

maak ik niet helemaal op wat je bedoeling is. Is dit een manier om de functie foo aan te roepen, en het resultaat toe te wijzen aan de tegelijkertijd gedeclareerde integer f1? En waarom geef je dan Int mee als argument voor de functie foo? En wat wil je met deze notatie bereiken? In andere woorden : een beetje uitleg op je huidige manier van werken zou wel handig zijn imho.

[ Voor 2% gewijzigd door NaliXL op 27-04-2003 23:41 . Reden: tags verkeerd ]

Genoeg is meer dan veel, en tart den overvloed


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Je zou ook eens naar Python kunnen kijken trouwens. Tiger is ook wel een interessant voorbeeld. Er is ook een hoofdstuk over hogere orde functies in Modern Compiler Implementation. Ik heb het boek hier echter niet bij de hand ...
Alarmnummer: En function heb ik nu vervangen door get_function
Wat vind je eigenlijk zo vreselijk aan:
code:
1
(Float):Float f = sin;

Je zal hier de rol van de identifier sin moeten achterhalen, maar het achterhalen van de rol van identifiers is toch wel een vrij normale bezigheid (denk aan instantie variabelen, lokake variabelen, methode argumenten).

Persoonlijk vind ik:
code:
1
f :: Float -> Float = sin;

ook veel duidelijker. Het pascal argument gaat naar mijn indruk niet echt op: mensen die alleen Pascal kennen, kunnen toch niet functioneel programmeren. Het lijkt mij sowieso wel verstandig om het type achter de identifier te zetten: dit doe je bij de functie declaratie ook en de identifier 'verdrinkt' dan wat minder in het type.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Je denkt natuurlijk dat je dan hier in de problemen komt:

code:
1
2
3
    ():Int f4 := function foo();
    Int x := foo();         
    return 10;


maar dat hoeft niet:
code:
1
2
3
    f4 :: -> Int := foo;
    x1 :: Int := f4();
    x2 :: Int := foo();

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Hum, hier heb je dan trouwens wel een probleem ....

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
foo :: -> Int
function foo()
   return 10;
 
foo :: Int -> Int
function foo(x)
   return x + 10;
 
foo :: (Int -> Int) -> Int
function foo(f)
   return f(3);
 
function main
   return foo(foo);

Je hebt hier dus flinke semantische analyse nodig, met mogelijk ambiguiteiten. Alleen declaraties kunnen die oplossen als er geen get_function is...

[ Voor 3% gewijzigd door mbravenboer op 28-04-2003 00:15 ]

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
NaliXL: Is dit een manier om de functie foo aan te roepen, en het resultaat toe te wijzen aan de tegelijkertijd gedeclareerde integer f1?
Nee, f1 is een functie, die je later nog kan toepassen of gewoon opleveren als resultaat. Dit ondersteunt mooi mijn argument aan dat Pascal kenners niet functioneel kunnen programmeren ;) .
En waarom geef je dan Int mee als argument voor de functie foo?
Om exact aan te geven welke functie hij bedoelt.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 15:12

alienfruit

the alien you never expected

Kun je niet wat leukers bedenken dan de standaard termen ;)
zoals function, return etc. :)

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

offtopic:
*drm slaat tussen de regels door mbravenboer even om de oren met de edit-knop ;)

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


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
mbravenboer schreef op 27 April 2003 @ 23:56:
Wat vind je eigenlijk zo vreselijk aan:
code:
1
(Float):Float f = sin;
Helemaal niets :) Maar je kan functies bij mij ook zonder haakjes schrijven. En dan kun je niet meer zien of je een functie aanroep of de functie zelf gaat halen. De reden dat ik functies zonder haakjes toelaat is dat ik bv alle record recordfields als functies kan schrijven:

function voornaam(Persoon p):String

en dan kan je zeggen:
persoon.voornaam
of
persoon.voornaam()
of
voornaam(persoon)
ook veel duidelijker. Het pascal argument gaat naar mijn indruk niet echt op: mensen die alleen Pascal kennen, kunnen toch niet functioneel programmeren. Het lijkt mij sowieso wel verstandig om het type achter de identifier te zetten: dit doe je bij de functie declaratie ook en de identifier 'verdrinkt' dan wat minder in het type.
Ik moet mijn syntax zeker nog iets consequenter gaan maken idd. Het is intussen een mengelmoesje aan het worden :)

[ Voor 10% gewijzigd door Alarmnummer op 28-04-2003 07:52 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
mbravenboer schreef op 28 April 2003 @ 00:13:
Hum, hier heb je dan trouwens wel een probleem ....

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
foo :: -> Int
function foo()
   return 10;
 
foo :: Int -> Int
function foo(x)
   return x + 10;
 
foo :: (Int -> Int) -> Int
function foo(f)
   return f(3);
 
function main
   return foo(foo);

Je hebt hier dus flinke semantische analyse nodig, met mogelijk ambiguiteiten. Alleen declaraties kunnen die oplossen als er geen get_function is...
Idd. En ik heb op dit moment niet de behoefte om de eigelijk best wel duidelijk 'get_function' te verwijderen. Je moet er rekening mee houden dat het ook nog te lezen moet zijn. En ook al zou ik geen problemen hebben met ambiguiteiten, dan zou het zelfs nog een goeie reden zijn om hem te gebruiken.

Ik heb gisteren nog even door mijn prologboek zitten struinen naar 'rules' (mijn baas is er wel eens mee bezig). En ik ben tot de conclusie gekomen dat rules alle prolog misschien een hele interessante toevoeging zijn. Je hoeft namelijk dan zelf niet meer te backtracken. Hou er rekening mee dat dit systeem gebruikt gaat worden als kennis systeem en dat dit soort handige zaken er niet in zouden misstaan.

vb:

code:
1
2
rule voorganger(X: Persoon, Z : Persoon)
      = ouder(X,Y) and voorganger(Y,Z)


Als je vanuit een niet rule een rule gaat aanroepen, dan krijg je voor de plaatsen waar je niets in hebt gestoken een array van waarden terug:


\\imperatief lezen.
Array<Persoon> voorgangers;
voorganger(in jan, out voorgangers)

[ Voor 26% gewijzigd door Alarmnummer op 28-04-2003 07:45 ]


  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
dit vind ik toch veel duidelijk om lezen:
code:
1
2
3
4
5
function blaat():Int 
begin 
    function f1 := foo(Int);
    return 10; 
end


met 'functie' dus all 'type' , waarom zou je nog eens de functie moeten verduidelijken (ie
(Int):int das dubbel werk). Tzal vast mijn invloed van Ecma SCript zijn waar Objects == functions (quasi). Misschien te indirect though?

In feite met de scheiding zoals vermeld heb je dan een 'interface' voor die functie/object:
code:
1
2
3
4
5
6
7
8
9
10
11
interface function toInt ():int; //persoonlijk vind ik c duideijk met zijn return type
 //eerst: dan ben je eigenlijk gewoon een type, aan het maken:
// int something(); something():int 
//je scrhijft toch niet: hallo:int bij het declaren? vond die altijd inconsequent in Pascal...

function hello 
   implements toInt
{


}

  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
mbravenboer schreef op 28 April 2003 @ 00:18:
[...]

Nee, f1 is een functie, die je later nog kan toepassen of gewoon opleveren als resultaat. Dit ondersteunt mooi mijn argument aan dat Pascal kenners niet functioneel kunnen programmeren ;) .
Nou ja, 't is duidelijk niet mijn pakkie an, maar zou je me misschien kunnen doorverwijzen naar een stukje uitleg over dergelijke code? Bovendien : je wilt toch niet zeggen dat Pascal-programmeurs geen mooie apps kunnen maken he? Anders kan ik zo wel ff een rijtje progs opnoemen die het tegendeel bewijzen....
* NaliXL is niet echt bekend met dingen als "een functie, die je later nog kan toepassen of gewoon opleveren als resultaat". Verder houdt NaliXL er niet echt van als mensen gaan lopen rochelen over zijn favo taal...
[...]
Om exact aan te geven welke functie hij bedoelt.
Okay, dus het gaat hier om een zgn. "overloaded" functie (= 2 functies met zelfde naam, onderscheid door argumenten)? Okay, maar is dat niet een beetje zinloos op deze manier? Ik bedoel, waarom dan niet gewoon 2 verschillende functie-namen?

Genoeg is meer dan veel, en tart den overvloed


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
NaliXL schreef op 28 April 2003 @ 12:58:
[...]

Nou ja, 't is duidelijk niet mijn pakkie an, maar zou je me misschien kunnen doorverwijzen naar een stukje uitleg over dergelijke code?
Het is een eigenschap van functionele programmeertalen. Je kan oa een functie meegeven als object. Stel dat ik de volgende functie heb om te controleren of een persoon ok is.

function ok(Persoon p):Bool
return p.heeftRoodHaar();

dan zou ik deze functie ook kunnen meegeven aan een lijst om daar dan alle rood hardige mensen uit te filteren. Maar als je alle mensen die ouder zijn dan 28, zou willen hebben, dan geef je een andere functie mee aan die filter functie.
[me=51802]is niet echt bekend met dingen als "een functie, die je later nog kan toepassen of gewoon opleveren als resultaat".
Bij functioneel programmeren kan je dus een functie zien als waarde, net zoals 1, "blaat" en true. En waardes kan je meegeven :)
Okay, dus het gaat hier om een zgn. "overloaded" functie (= 2 functies met zelfde naam, onderscheid door argumenten)? Okay, maar is dat niet een beetje zinloos op deze manier? Ik bedoel, waarom dan niet gewoon 2 verschillende functie-namen?
He gedsie, we leven niet meer in de middeleeuwen ;)

[ Voor 3% gewijzigd door Alarmnummer op 28-04-2003 13:41 ]


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
NaliXL: Nou ja, 't is duidelijk niet mijn pakkie an, maar zou je me misschien kunnen doorverwijzen naar een stukje uitleg over dergelijke code?
Alarmnummer heeft al het een en ander uitgelegd en voor meer info kan je eens rondneuzen op de website van Haskell (zie sig). Ook is er nog een goede college dictaat van functioneel programmeren beschikbaar: http://www.cs.uu.nl/~jeroen/
Bovendien : je wilt toch niet zeggen dat Pascal-programmeurs geen mooie apps kunnen maken he?
Rustig maar hoor, ik wilde je niet beledigen ;) . Het is geen schande om niet bekend te zijn met functioneel programmeren: lang niet elke opleiding (zeker niet academische) besteden daar (verplicht) aandacht aan. De benaming "functioneel" heeft ook niets te maken met 'werkend', maar met de opzet van de taal: volledig gericht op functies. Een pure functionele taal kent geen state: je kan de waarde van een variabele niet aanpassen en er zijn in feite geen assigments. Programmeren zonder te werken met een een state is voor programmeurs die alleen ervaring met imperatieve talen werken erg lastig. Vandaar mijn opmerking dat Pascal kenners niet functioneel kunnen programmeren. Java, C#, PHP, VB .NET, C en C++ kenners dus ook niet.
Verder houdt NaliXL er niet echt van als mensen gaan lopen rochelen over zijn favo taal...
Jaja ... Volgens mij kan je wel even wat ontspanning gebruiken :P . Zo enthousiast heb ik me nergens over uitgelaten (en anders zou ik het wel over Stratego doen :P ). Ik zou me wat minder aggressief/geprikkeld opstellen als je ergens gewoon geen kennis van hebt. Het ontbreken van kennis is geen enkel probleem: daar is onze maatschappij op ingericht ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • NaliXL
  • Registratie: Maart 2002
  • Laatst online: 30-07 19:19
Oh, okee mensen, nou begint het mij pas te dagen dat het hier om een heel andere manier van programmeren gaat dan ik gewend ben. En idd, ik dacht dat met "functioneel programmeren" het bruikbaar zijn van de taal bedoeld werd.

Verder wil ik nog ff mijn excuses aanbieden aan Alarmnummer. Dat ik zo geprikkeld deed komt vooral door het feit dat, op de meeste forums waar ik post, ik altijd eerst een lijstje flames over pascal als reply krijg voordat ik een bruikbaar antwoord krijg, meestal door newbies die denken dat je alleen met C of C++ programma's kunt schrijven. Dat is op z'n minst gezegd zeer ergerlijk....

Genoeg is meer dan veel, en tart den overvloed


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Ik denk dat je mbravenboer bedoelt. Maar als je wilt mag je je ook wel bij miij excuseren hoor :P

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Is (was) al goed hoor :> . De term functioneel programmeren zorgt wel vaker voor grote misverstanden ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment

Pagina: 1