LINQ for Go

已查看 1,698 次
跳至第一个未读帖子

Ahmet Alp Balkan

未读,
2014年1月4日 00:31:502014/1/4
收件人 golan...@googlegroups.com
Hi folks,

After reading number of historical threads in this group about how unsuitable Go is for something like LINQ (language integrated query) since there are no generics and lambdas, I funnily decided to do this anyway –and it is finally here. This is my first project in Go. Please check it out:


The library provides methods to query and manipulate objects in in-memory slices, inspired by Microsoft's LINQ library. There are similar projects for Go like fn and gen where one is functional tools and other provides LINQ-like functionality with code generation for type safety, respectively. Here are highlights about what I have built:

* DRY: If your code has a significant SQL-like operations for in-memory objects, this library might help you to do not repeat yourself.
* Accepts slices of any type: There's a reflection hack makes this possible.
* No type safety: You have to make assertions to the type you expect in all predicate/selector functions. Type assertion makes it just a bit slower. Also, need to have 100% code coverage for LINQ code you are writing.
* Parallelization: I implemented PLINQ (parallel linq) using goroutines. So this actually might have a real use in Go projects. There's an example in the wiki about this.
* Strict error handling: Since queries may involve IO operations or calls to other packages, you will see a lot of error parameters here and there. It makes things a lot uglier but Go-ish. I am looking for ways to reduce it without restricting users any further on strict error handling.
* Hard to debug: Since you will end up a query method chain like From().Where().Select().Count(), any error occurred during the query will be returned at the very end propagating through all the methods in the rest of the chain. But it's the same case in .NET anyways, I kept this approach as-is.

I call it v0.9 at this point and I believe you guys might kindly provide some feedback to improve it. It also seems to me like such project has no place in Go ecosystem but a day might come where we can have generics (or even lambdas) and then there will be people who can make use of this library. However, current state of Go is not making things any easier for such type of programs, I suppose there is no harm in doing this project and my motivation was to be just make something useful out of my time.

There are already a few kind tweets about it:

So, I appreciate your feedback, contributions and stars.

Regards,
Alp.

p.s. you might say it's not really 'language integrated' but Microsoft uses the term LINQ for method syntax as well. 

Andrew Gallant

未读,
2014年1月4日 02:14:252014/1/4
收件人 golan...@googlegroups.com
You may be able to improve error messages (for type errors) with https://github.com/BurntSushi/ty (I am the author).

- Andrew

Ibrahim M. Ghazal

未读,
2014年1月4日 03:41:512014/1/4
收件人 Ahmet Alp Balkan、golang-nuts
Minor nitpick: putting the dot on a new line doesn't work because of
Go's semicolon-insertion.

So in <http://ahmetalpbalkan.github.io/go-linq/> :

results, err := From(students)
.Where(func (s T) (bool, error){

Should really be:

results, err := From(students).
Where(func (s T) (bool, error){

Ahmet Alp Balkan

未读,
2014年1月4日 03:49:172014/1/4
收件人 Ibrahim M. Ghazal、golang-nuts
Oops, entirely my bad, I just written the whole thing in HTML without ever gofmting. Fixed now. Thanks.

– Alp.

Donovan Hide

未读,
2014年1月4日 08:01:552014/1/4
收件人 Ahmet Alp Balkan、Ibrahim M. Ghazal、golang-nuts
Who needs generics :-)

I will be using this! Well done!


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Ahmet Alp Balkan

未读,
2014年1月4日 13:06:552014/1/4
收件人 Andrew Gallant、golang-nuts
Thanks Andrew, I will definitely check this out.

Best,
– Ahmet Alp.

--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/nLwWkoS7Bh8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.

jimmy frasche

未读,
2014年1月4日 14:19:112014/1/4
收件人 Ahmet Alp Balkan、Andrew Gallant、golang-nuts
Instead of taking funcs whose parameters are interface{} you could
take an interface{} and use reflection to dynamically type check that
it's a func of the correct signature or even allow some variations of
the func allowed, like making error optional.

If you use reflection throughout your quickstart example could be

var students []*Student
var over18names []string
//set students
err := linq.From(students).
Where(func(s *Student) bool { //we know this has to be *Student
from the type of students
return s.age >= 18
}).
Select(func(s *Student) string {
return s.name
}).
Results(&over18names) //we know this has to be []string from the
return value of the func in Select

Having to go through reflect will make the function call overhead
greater but you can skip copying everything into a []interface{}, but
if you cared about speed you'd just write:

var over18names []string
for _, s := range students {
if s.age >= 18 {
over18names = append(over18names, s.name)
}
}

Ahmet Alp Balkan

未读,
2014年1月4日 14:29:272014/1/4
收件人 jimmy frasche、Andrew Gallant、golang-nuts
Thanks Jimmy, great suggestions indeed. I started prototyping Query.Results(*slice) approach myself a few days ago but still having a few problems with it I am hoping to solve.

Converting function signatures to interface{} could make things really messy for users since there are 3 types of functions taken as parameters (takes object returns bool, takes object returns another, takes 2 objects return bool by comparing) throughout the library. Also the package documentation would be pretty much unreadable without examples and usage will be more prone to errors.

Yes it'll bring features like optional error handling. Once I start creating several benchmarks for the package, I will start another branch for this and see how it slows down things since calls to the input functions will be through reflection for every single element of slice, which will be as you said, costly.

Thanks,
-Alp

jimmy frasche

未读,
2014年1月4日 14:38:042014/1/4
收件人 Ahmet Alp Balkan、Andrew Gallant、golang-nuts
On Sat, Jan 4, 2014 at 11:29 AM, Ahmet Alp Balkan
<ahmetal...@gmail.com> wrote:
> Thanks Jimmy, great suggestions indeed. I started prototyping
> Query.Results(*slice) approach myself a few days ago but still having a few
> problems with it I am hoping to solve.

What problems were you having?
已删除帖子

nafiy...@gmail.com

未读,
2014年1月29日 01:43:102014/1/29
收件人 golan...@googlegroups.com

4 Ocak 2014 Cumartesi 07:31:50 UTC+2 tarihinde Ahmet Alp Balkan yazdı:
回复全部
回复作者
转发
0 个新帖子