[Swift] Swift en functional relational mapping?

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Lethalis
  • Registratie: April 2002
  • Niet online
Waarschijnlijk ben ik heel kippig, maar ik heb al een paar uur op Google gezocht en het niet kunnen vinden.

Inleiding: Hoe het werkt in C# en Scala (en met workaround inmiddels ook in Java)

Als je met C# programmeert, kun je zelf zogenaamde LINQ providers maken. Dat wil zeggen dat het mogelijk is om zelf LINQ expressions te parsen.

Een voorbeeldje hiervan kun je vinden op: http://blogs.msdn.com/b/m...ble-provider-part-ii.aspx

Het staat het vertalen van LINQ expressies naar SQL toe bijvoorbeeld. In het Entity Framework kun je LINQ gebruiken om de database te queryen hierdoor:

code:
1
var blog = context.Blogs.Where(b => b.Name == "ADO.NET Blog").FirstOrDefault();


Ook nHibernate maakt met QueryOver<T> dankbaar gebruik van deze mogelijkheid:

code:
1
IList<Cat> cats = session.QueryOver<Cat>().Where(c => c.Name == "Max").List();


In Java wordt dit standaard niet ondersteund, maar heeft iemand zoiets dergelijks gebouwd door de lambda expressions serializable te maken en daarna byte code analysis toe te passen:

https://github.com/TrigerSoft/jaque

Java 8 lambda's worden dan vertaald naar expression trees, waardoor het in de toekomst mogelijk is om ook een QueryOver<T> voor Hibernate te bouwen.

Ook in een taal als Scala is het mogelijk om functional relational mapping toe te passen, getuige de Slick ORM library:

http://slick.typesafe.com...tional-relational-mapping

Het is dus mogelijk om een class te bouwen die functies als filter en map heeft die predicaten ontvangen, en deze vervolgens als een expression tree te parsen om er daarna iets anders mee te doen, bijvoorbeeld SQL genereren.

code:
1
2
3
// Query that limits results by price < 10.0
// Equivalent SQL: select * from COFFEES where PRICE < 10.0
coffees.filter(_.price < 10.0)


Het grote voordeel hiervan is dat je strongly typed queries krijgt die refactoring ondersteunen.

Apple: Swift wordt open source

Dus ik word enthousiast :P En begin de taal te bestuderen en uit te zoeken of het wel alles heeft dat ik wil.

En dit is nou net zo'n dingetje wat ik niet heb kunnen vinden.

Ondersteunt Swift nou expression tree parsing van functionele expressies en kun je daardoor ook API's bouwen die functional relational mapping ondersteunen? Of niet?

Ik kan het niet vinden tot nu toe, wat mij een beetje droevig stemt, gezien ik een grote fan ben van deze mogelijkheid in C# en Scala ;)

Alvast bedankt.

Ask yourself if you are happy and then you cease to be.


Acties:
  • 0 Henk 'm!

  • n8n
  • Registratie: Juni 2007
  • Laatst online: 12-10 20:10

n8n

Ik ben niet helemaal bekend met de lingo, maar het doet me denken aan pattern matching. Shoot me if I’m wrong, anders hier een link over Swift 2 met uitleg over vernieuwingen daarin:

[YouTube: https://youtu.be/gaXSbqo3iKA?t=18m24s]

18:24

[ Voor 3% gewijzigd door n8n op 13-06-2015 19:25 ]


Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Lethalis schreef op donderdag 11 juni 2015 @ 07:55:
Waarschijnlijk ben ik heel kippig, maar ik heb al een paar uur op Google gezocht en het niet kunnen vinden.

Inleiding: Hoe het werkt in C# en Scala (en met workaround inmiddels ook in Java)

Als je met C# programmeert, kun je zelf zogenaamde LINQ providers maken. Dat wil zeggen dat het mogelijk is om zelf LINQ expressions te parsen.
'zelf' een linq provider maken is op papier een leuk project, maar het gaat je zoveel tijd kosten dat je het in je eentje alleen af krijgt wanneer je er full time een lange tijd aan werkt (mijzelf kostte het ong 9-10 maanden full time development).
Een voorbeeldje hiervan kun je vinden op: http://blogs.msdn.com/b/m...ble-provider-part-ii.aspx
Matt Warren is een van de linq to sql programmeurs en zijn OSS provider is een deel van de linq to sql provider, maar staar je er niet blind op: de linq provider in linq to sql zelf is vele malen groter.

"Don't try this at home" is m.i. een goed advies in dit kader :)
Het staat het vertalen van LINQ expressies naar SQL toe bijvoorbeeld. In het Entity Framework kun je LINQ gebruiken om de database te queryen hierdoor:

code:
1
var blog = context.Blogs.Where(b => b.Name == "ADO.NET Blog").FirstOrDefault();


Ook nHibernate maakt met QueryOver<T> dankbaar gebruik van deze mogelijkheid:

code:
1
IList<Cat> cats = session.QueryOver<Cat>().Where(c => c.Name == "Max").List();
Deze twee voorbeelden zijn niet hetzelfde. NHibernate's query over maakt gebruik van methods/extension methods zoals de 'Where' hier, die een Expression<Func<>> als argument krijgen en ze parsen die ter plekke. Bij EF is dit anders, die krijgen het volledige statement als een expression tree en parsen de volledige tree. Bij NHibernate is dit niet nodig, want .QueryOver<T> levert al een object op waar de .Where() een call op is, het is in feite een in-line DSL.
Het is dus mogelijk om een class te bouwen die functies als filter en map heeft die predicaten ontvangen, en deze vervolgens als een expression tree te parsen om er daarna iets anders mee te doen, bijvoorbeeld SQL genereren.

code:
1
2
3
// Query that limits results by price < 10.0
// Equivalent SQL: select * from COFFEES where PRICE < 10.0
coffees.filter(_.price < 10.0)


Het grote voordeel hiervan is dat je strongly typed queries krijgt die refactoring ondersteunen.
Maar je hoeft geen expression trees te gebruiken voor strongly typed query systems ;) Wat je nodig hebt is een in-line DSL, die werken net zo goed, zoniet beter: Linq is bv gericht op sequences, maar databases werken in sets en SQL heeft andere scoping rules dan een sequence based statement serie, waar een operatie altijd werkt op het resultaat van een vorige operatie. Dit levert het probleem dat wanneer je een SQL query wilt uitvoeren maar je linq moet gebruiken, je een vertaling naar linq moet doen, die niet 1 2 3 voor de hand hoeft te leggen. Bij een in-line DSL is dat veelal veel beter geregeld want je kunt die bv richten op het direct vertalen naar SQL. Ik heb om die reden ook een in-line DSL gemaakt naast onze Linq provider (en de low-level native api). Deze in-line DSL ('Query Spec') maakt gebruik van generated types voor bv velden van entities en extension methods om expressies en predicates op te bouwen. Zodoende hoef ik geen hele expression trees te bouwen. (ik gebruik alleen expression trees in de projection naar types zodat men alle mogelijke code kan toevoegen aan zo'n expression).
Apple: Swift wordt open source

Dus ik word enthousiast :P En begin de taal te bestuderen en uit te zoeken of het wel alles heeft dat ik wil.

En dit is nou net zo'n dingetje wat ik niet heb kunnen vinden.

Ondersteunt Swift nou expression tree parsing van functionele expressies en kun je daardoor ook API's bouwen die functional relational mapping ondersteunen? Of niet?

Ik kan het niet vinden tot nu toe, wat mij een beetje droevig stemt, gezien ik een grote fan ben van deze mogelijkheid in C# en Scala ;)
Ik ken swift verder niet, maar als het iets van extension achtige methods ondersteunt, of operator overloading, of andere vormen waarmee je een in-line DSL kunt maken zou ik daar in eerste instantie naar kijken. Ook met bv een code generator kom je een heel eind om bv classes te maken die je kunt gebruiken voor het bouwen van queries.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Acties:
  • 0 Henk 'm!

  • Lethalis
  • Registratie: April 2002
  • Niet online
EfBe schreef op zondag 14 juni 2015 @ 10:13:
[...]
'zelf' een linq provider maken is op papier een leuk project, maar het gaat je zoveel tijd kosten dat je het in je eentje alleen af krijgt wanneer je er full time een lange tijd aan werkt (mijzelf kostte het ong 9-10 maanden full time development).
Het gaat mij er niet zozeer om dat ik er zelf 1 maak. Ik ben meer geinteresseerd in de mogelijkheden die de taal biedt, om te kunnen beoordelen of dit soort zaken op termijn door de community opgepakt kunnen worden :)
Deze twee voorbeelden zijn niet hetzelfde. NHibernate's query over maakt gebruik van methods/extension methods zoals de 'Where' hier, die een Expression<Func<>> als argument krijgen en ze parsen die ter plekke. Bij EF is dit anders, die krijgen het volledige statement als een expression tree en parsen de volledige tree. Bij NHibernate is dit niet nodig, want .QueryOver<T> levert al een object op waar de .Where() een call op is, het is in feite een in-line DSL.
Bedankt voor dit inzicht!

Ik zal zodra ik terugkom van mijn vakantie eens naar de sourcecode van nHibernate QueryOver<T> kijken. Want hoewel je natuurlijk gelijk hebt dat je met QueryOver<T> reeds een object hebt waar je mee verder kunt werken, vraag ik me alsnog af wat ervoor nodig om de functionele expressie in de .Where() te vertalen naar bijv. SQL.

Je ziet bij Java bijvoorbeeld dat dit nog niet gebeurt in libraries zoals QueryDSL. Geen idee of de Java 8 streams API hier verandering in kan brengen. Nog zo'n ding dat ik wil leren :)
Maar je hoeft geen expression trees te gebruiken voor strongly typed query systems ;) Wat je nodig hebt is een in-line DSL, die werken net zo goed, zoniet beter: Linq is bv gericht op sequences, maar databases werken in sets en SQL heeft andere scoping rules dan een sequence based statement serie, waar een operatie altijd werkt op het resultaat van een vorige operatie. <knip>
Met dit inzicht ga ik zeker eens verder kijken. Bedankt :)
Ik ken swift verder niet, maar als het iets van extension achtige methods ondersteunt, of operator overloading, of andere vormen waarmee je een in-line DSL kunt maken zou ik daar in eerste instantie naar kijken. Ook met bv een code generator kom je een heel eind om bv classes te maken die je kunt gebruiken voor het bouwen van queries.
Zal ik naar kijken!

Ask yourself if you are happy and then you cease to be.


Acties:
  • 0 Henk 'm!

  • Lethalis
  • Registratie: April 2002
  • Niet online
https://github.com/nhiber...rc/NHibernate/ISession.cs

https://github.com/nhiber.../NHibernate/IQueryOver.cs

Overal Expression<Func<T>> :) Dus die parsen ze wel. .Net bouwt hier een expression tree voor je op en dat is nou waarvan ik me afvraag of het in Swift kan :)

[ Voor 46% gewijzigd door Lethalis op 14-06-2015 16:23 ]

Ask yourself if you are happy and then you cease to be.


Acties:
  • 0 Henk 'm!

  • Lethalis
  • Registratie: April 2002
  • Niet online
n8n schreef op zaterdag 13 juni 2015 @ 19:25:
Ik ben niet helemaal bekend met de lingo, maar het doet me denken aan pattern matching. Shoot me if I’m wrong, anders hier een link over Swift 2 met uitleg over vernieuwingen daarin:

[video]

18:24
Ik ga hem helemaal kijken :)

Ask yourself if you are happy and then you cease to be.


Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Lethalis schreef op zondag 14 juni 2015 @ 16:03:
https://github.com/nhiber...rc/NHibernate/ISession.cs

https://github.com/nhiber.../NHibernate/IQueryOver.cs

Overal Expression<Func<T>> :) Dus die parsen ze wel. .Net bouwt hier een expression tree voor je op en dat is nou waarvan ik me afvraag of het in Swift kan :)
Nou 'parsen' is wel wat veel eer hoor :) In theorie kan nl. een complete query in die where predicate zitten maar ze nemen een shortcut en nemen aan dat het een directe predicate is op het generic type argument van de QueryOver, eventueel met navigation (a.b.c.Field==foo), maar ik denk zelfs dat niet.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com

Pagina: 1