andy128k / cl-gobject-introspection

BSD 2-Clause "Simplified" License
49 stars 15 forks source link

Interface suggestion #30

Closed hying-caritas closed 10 years ago

hying-caritas commented 10 years ago

IMHO, there is two issues for current cl-gobject-introspection interface.

1) "call" is used to get constant and enum value, that is not very intuitive.

For example: (call gtk "WindowType" :toplevel)

According to my understanding of gobject object system, library (gtk here), class, enumeration are all kind of namespace. To get a function/const/enum/class from the library is kind of namespace access, to get a method from object is kind of namespace access too. So I suggest to introduce that kind of concept into cl-gobject-introspection too. Add a new function named nget (namespace get) as follow:

(nget gtk "WindowType" :toplevel) -> get enum value (nget gtk "Window" 'new) -> get a class constructor function (nget window 'add) -> get a method

2) In object method calling, there is no syntax to distinguish between "getting the function/method" and the function/method parameters.

For example:

(call gtk "Window" 'new 0)

Where, "gtk", "Window" "'new" is used to get the constructor function, "0" is the parameter for the function. I think it may be better to do some distinguish between them. Such as something like:

(call (nget gtk "Window" 'new) 0)

To save some typing, we can introduce a macro say gcall (gobject call) as follow:

(gcall (gtk "Window" 'new) 0)

In this way, (gtk "Window" 'new) can be seen as function and "0" can be seen as parameters.

And after some experiment, I found it is not hard to implement this.

What do you think about this?

Kalimehtar commented 10 years ago

I would save current API. such as

(defmacro call (&rest args)
   (if (listp (car args))
       `(gcall (nget ,@(car args)) ,@cdr args)
       `(nget ,@args)))
andy128k commented 10 years ago

IMHO gcall sounds ugly. What about "invoke"?

hying-caritas commented 10 years ago

I am not good at naming, because I am not good at English. I will accept your naming suggestion. What about "nget"? Do you think it is a good name?

andy128k commented 10 years ago

nget is supposed to return wrapper for an introspection object, which is derived from GIBaseInfo. What about "info"?

andy128k commented 10 years ago

Since we discuss interface changes, I would propose to add "property", "(setf property)", "field", "(setf field)" similar to "gcall".

Exclamation mark in setter is nice but too schemish :)

What do you think?

andy128k commented 10 years ago

@Kalimehtar Should we really keep current API? We could move such code to extra package (gir-compat).

hying-caritas commented 10 years ago

On Tue, Apr 15, 2014 at 7:18 PM, Andrey Kutejko notifications@github.comwrote:

nget is supposed to return wrapper for an introspection object, which is derived from GIBaseInfo. What about "info"?

Sometimes not wrapper for an introspection object. For example

(nget gtk "WindowType" :toplevel)

Will return a fixnum.

hying-caritas commented 10 years ago

Since we discuss interface changes, I would propose to add "property", "(setf property)", "field", "(setf field)" similar to "gcall".

Exclamation mark in setter is nice but too schemish :)

What do you think?

Sounds good for me.

Kalimehtar commented 10 years ago

Should we really keep current API

I'm not so about compat, but about omit extra parens. There should be handy API for user. (nget ...)-style is good for higher order functions. But for me

window.add(gtk.label.new("ok"))

should be

(call window 'add (call gtk 'label 'new "ok"))

or even (we may make a macro, that quote name for method or class)

(@ window add (@ gtk label new "ok"))

and should not be

(call (nget window add) (call (nget gtk label new) "ok"))
hying-caritas commented 10 years ago

and should not be

(call (nget window add) (call (nget gtk label new) "ok"))

We can make this a little better:

(gcall (window add) (gcall (gtk label new) "ok")

But it is still 2 more pairs parens than your version.

andy128k commented 10 years ago

Just for inspiration: http://clojuredocs.org/clojure_core/clojure.core/-%3E http://clojuredocs.org/clojure_core/clojure.core/-%3E%3E

hying-caritas commented 10 years ago

For me, -> is a good replacement for "nget", especially I have seen it used in similar way in C/C++/perl.

andy128k commented 10 years ago

-> is (can be) more general than nget.

(-> *gtk*
    "Button"
    (invoke 'new 0))
Kalimehtar commented 10 years ago

-> is (can be) more general than nget

And cannot be used in mapcar, for example. -> is a good macro, but bad base API.

hying-caritas commented 10 years ago

I think we can start with the stuff we have consensus firstly. That is, Add "nget", "gcall", and keep "call" at least for now. We can add "->" in the future based on "nget" and "gcall".

As for naming, the formal name of "gcall" will be "invoke", but I don't think "info" is good replacement for "nget", any suggestion?

Kalimehtar commented 10 years ago

any suggestion

I'm agree with it. So add "nget" and "invoke" and replace "call" with a macro. This way we will have an opportunity to change internal presentation for repository and objects from lambdas to structs.

andy128k commented 10 years ago

I personally don't like than nget has special case for enum values. Enum value is a GIValueInfo. This fits to "info".

One more thing. I am not sure somebody needs raw integer value for enum/bitfield. But "invoke" can take both GIValueInfo and fixnum.

hying-caritas commented 10 years ago

One more thing. I am not sure somebody needs raw integer value for enum/bitfield.

I think raw integer is better for readability. And we finally need the raw integer value to fill in function argument.

And not only the enum, we need raw integer and string for const too.

hying-caritas commented 10 years ago

On Tue, Apr 15, 2014 at 5:01 PM, Kalimehtar notifications@github.comwrote:

I would save current API. such as

(defmacro call (&rest args) (if (listp (car args)) (gcall (nget ,@(car args)) ,@cdr args) (nget ,@args)))

It appears that this will not keep original "call" syntax exactly.

Originally, it is:

(call gtk "Window" 'new 0)

With your macro, it will be:

(call (gtk "Window" 'new) 0)

I want to double check is this what you want? Because if appears to keep originally "call", we need to convert everything except function to struct firstly.

Kalimehtar commented 10 years ago

Oh. I failed. Then drop "call". New API is better.

hying-caritas commented 10 years ago

OK. And I will keep using "nget" until we find a better name.