Hi,
My name is Rafael Schloming, I'm one of the proton developers over at
qpid.apache.org. I've recently been looking into the possibility of using
clownfish to deal with some of the maintenance issues we have with the
proton bindings, and Marvin was kind enough to send me an early version of
a tutorial in exchange for some feedback. He asked me to share it with this
list, so I've included it below.
FYI, this was initially sent to Marvin directly, so he is the "you" I'm
referring to below.
--
The first part is basically a roughly chronological stream of consciousness
log of whatever popped into my head as I progressed. As such it is likely
that some of those items may just be random thoughts rather than actionable
items. After that I've attempted to capture some more distilled thoughts.
- I noticed there isn't really an overview of what clownfish is, it just
jumps straight into the tutorial. This was fine for me, but I can't help
but feel I probably have a leg up given that I got the overview from you in
person. This kind of made me wonder about the audience in general for
clownfish. I have some more questions/thoughts about this later.
- Poking around briefly after the git clone, I noticed there seems to be a
very regular directory structure. It left me curious about the model behind
it.
- Minor nit. The back ticks can be a bit hard to read. Maybe use $(pwd) for
people with old eyes like me. ;-)
- The multiple build steps piqued my curiosity. Is it actually necessary to
have multiple build steps for some reason?
- My initial build was actually on the master branch. I switched to tut1
branch after the first build and did a rebuild with this result:
make: *** No rule to make target
`../core/Clownfish/Test/TestVector.cfh', needed by
`autogen/hierarchy.json'. Stop.
Rerunning configure seemed to fix the issue.
- The above few things made me wonder about basic model of the build system.
- My kneejerk reaction upon first seeing the API usage in hello2.c was
something along the lines of "ugh, long prefix and lots of capitalization".
- I like the string constructor using the format strings. This seems to
remove a bunch of boilerplate relative to "normal" C code.
- I notice that accessing the string contents as utf8 requires memory
allocation in this example. This could be an issue for proton given that it
needs to efficiently round trip utf8 strings on/off of the wire.
- The short names option is nice. I wonder if it might also be nice to have
an intermediate option, e.g. cf or something like that.
- I notice that the type name and method prefix don't match for String.
Proton has a pretty strong convention of using pn_<class>_t and
pn_<class>_method.
- Why do I need to know/care about the difference between dynamic and inert
calls when I'm making them? What if I change from one to the other? is
there something that prevents me from doing this or do I need to decide
what will be dynamic vs inert from the beginning?
- There is no listing for hello3.c in the tutorial text.
- The core/c/perl thing could use some explanation. Again I feel like I
want some sort of build system/directory structure overview.
- What does hello_bootstrap_parcel() do?
- Where does GREETER come from?
- The utf8 access pattern seems to incur extra cognitive overhead for
memory management.
- Can I use a single mutable string object and pass it in as an out
parameter?
- The hello3 example seems like a big jump, there are lots of new
unexplained concepts. Could probably do with a few more baby steps.
- The host languages part seems to give a little bit of a description of
what clownfish is, but almost from the perspective of explaining why I have
to build separately for perl. This seems a bit out of place here.
- Do I actually have to clean up the C to build the perl?
- When I tried building perl I hit this issue:
[rhs@localhost perl]$ perl Build.PL
Base class package "Module::Build" is empty.
(Perhaps you need to 'use' the module which defines that package first,
or make that module available in @INC (@INC contains: lib buildlib
/home/rhs/lucy-clownfish/runtime/perl/blib/lib
/home/rhs/lucy-clownfish/runtime/perl/blib/arch
/home/rhs/lucy-clownfish/compiler/perl/blib/lib
/home/rhs/lucy-clownfish/compiler/perl/blib/arch /usr/local/lib64/perl5
/usr/local/share/perl5 /usr/lib64/perl5/vendor_perl
/usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .).
at lib/Clownfish/CFC/Perl/Build/Charmonic.pm line 21.
BEGIN failed--compilation aborted at
lib/Clownfish/CFC/Perl/Build/Charmonic.pm line 21.
Compilation failed in require at (eval 2) line 2.
...propagated at /usr/share/perl5/base.pm line 84.
BEGIN failed--compilation aborted at buildlib/Clownfish/CFC/Build.pm line
27.
Compilation failed in require at Build.PL line 20.
BEGIN failed--compilation aborted at Build.PL line 20.
[rhs@localhost perl]$
Ok, that's the end of my stream of consciousness thoughts. As for my
*slightly* more distilled thoughts. It strikes me that there are a couple
of different possible audiences for a tool like clownfish. One audience is
people like me who need to write C code and provide bindings in lots of
different languages. The other possible audience is someone who is working
in a single high level language, e.g. python/ruby/etc, but wants to build a
hybrid system with some parts in C.
I wonder if the tutorial isn't starting a bit too much from the perspective
of that first audience, e.g. it starts with the C and doesn't (yet) talk
much about the high level language. I wonder if it might in some ways be
better to start from the perspective of the second audience, e.g.have the
top level of the tutorial basically be a language picker (vaguely like
this: https://stripe.com/us/features) and once you've chosen the language
you want, the focus of the tutorial could be to get you as quickly as
possible to writing your python/ruby/etc object in C.
I realize this doesn't directly tout one of the coolest features of
clownfish (getting multiple language bindings for free), however I think
the approach you have could eliminate a lot of the boilerplate even for the
single language case, and given that I suspect the latter audience is
somewhat larger than the former audience, it might make sense as a goal to
make clownfish be the preferred way of writing bindings in language X for
as many different X's as you can manage. The fact that a binding written
this way for language X can also work for language Y is an awesome feature,
but given my assumption about the audience sizes, it isn't necessarily the
right framing for the tutorial.
Ok, that was a bit more meandering than distilled, but hopefully useful. ;-)
--Rafael