Il giorno lunedì 1 ottobre 2012 16:45:44 UTC+2, tbc++ ha scritto: > > I've thought about this as well. Coming from the .NET world I'm quite > familiar with the Linq.Expression namespace. I too have wondered about > this. For those who are not familiar with how IQueryable<T> works in Linq, > it's something like the following (in clojure): > > > (def query (q (db :people) > (where #(> (:age %) 21)) > :last-name > distinct)) > > The (db :people) call will return a IQueryable object. The q macro will > then take all the clauses in the query, wrap them up into an AST, and then > create a lazy seq. At this point in the code, nothing has been executed. > Upon calling (first query), the q macro hands the AST to the IQueryable > object, and then calls Execute on the object. Execute does whatever it > pleases with the AST, and then returns a lazy seq of the results. > > A C# tutorial on this, is available here ( > http://wekeroad.com/2007/07/02/linq-how-to-use-linq-to-query-just-about-anything/ > ) > > I see this fitting into the Clojure ecosystem in a very interesting way: > > Seq abstraction - > Lazy evaluation > Must run on the local CPU (for map, reduce, etc.) > Must run in order > Data provider can't influence execution > > Reducers - > Data provider can influence execution > Must run on the local CPU > Can run in any order > > IQueryable abstraction - > Data provider has full control over execution > Code can be run anywhere > Provider must compile code. > > > Example providers of IQueryable: > > Entity Framework (Linq over SQL) > Linq to XML (Linq over XML) > Linq to GPU (run queries on a graphics processor) > http://brahma.ananthonline.net/ > I've also seen index providers for in-memory data structures > > > So, I guess the original question still remains. Would Clojure benefit > from an AST abstraction? I know we have macros, but is that enough? > > I'd love input on this topic. > > The missing feature is not AST abstraction, but rather compile-time access to an environment with enough meaningful static type information.
An AST abstraction is a representation of (part of) a program's syntax as data structures and functions that can operate on them. All Lisps have it; most, like Clojure and Common Lisp, have it in the simple form of S-Expressions, while others, like some (all?) Scheme dialects, use more complex objects that can hold additional information, such as the file name and line number they were parsed from. C# has an AST abstraction too, which, as far as I know, is limited to the subset of the language usable in the body of lambda expressions. The C# AST implementation is strongly typed, whereas in Lisp the AST is only loosely typed, because while each atom is of a well-known type, compound expressions are just lists (or sometimes, in Clojure, vector or maps). This is an important difference, but it has no impact on the implementation of something like LINQ. In fact, the AST abstraction is only one leg of the support for LINQ in C#; the other important aspect is that LINQ is able to generate different code depending on the static type of the object being queried. Querying a collection will generate code to map, filter etc. that collection, while querying a database connection will generate code that submits SQL queries to the RDBMS. You cannot generally do that in Lisp because you cannot know the static type of the variables that a macro is invoked on; you would have to generate code that dispatches at runtime (which might be perfectly acceptable, mind you, but is not the same thing as LINQ). As part of the Common Lisp standardization process, there was a proposal for an environment access API that exposed the lexical environment to macro writers. The feature did not become part of Common Lisp, but it is described in CLtL2, and some CL implementations provide it even if it's not in the standard. With that feature and a good type inference engine, it would be possible for a macro to generate code depending on the static type of one or more of its arguments, because you could query the environment for the type of each variable. Alessio Stalla -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en