CppCast - SQLpp11
Episode Date: May 7, 2015Rob and Jason are joined by Roland Bock to talk about sqlpp11 and some of Rolands ideas for the future of C++ Roland Bock is Head of Development at PPRO Financial Ltd, an FCA regulated e-Money... institute offering prepaid MasterCard card programs and comprehensive financial solutions for international electronic payment transactions. Since 2008 he has been using SQL in C++. Being unhappy with the string-based approach of most SQL libraries, he decided to do something about it and developed a type-safe EDSL for SQL in C++: sqlpp11. In his spare time Roland is working on sqlpp11, experimenting with Concepts Lite and trying to write a proposal about compile-time configurable names for C++ standard. He lives and codes in Munich (Germany). News C++ 11/14/17 Features in VS 2015RC C++ 11 Constant Expressions in VS 2015 RC Resumable Functions in C++ C++ highlights and more of GCC 5.1 Roland Bock Roland Bock on github Thoughts by Roland Bock Links sqlpp11 Dreaming of Names ISO C++ Standard Discusson on Names Sponsors
Transcript
Discussion (0)
This episode of CppCast is sponsored by JetBrains, maker of excellent C++ developer tools.
Listen in for a special discount code later this episode.
And by CppCon, the annual week-long face-to-face gathering for the entire C++ community.
The call for CppCon 2015 submissions is now open with a deadline of May 22nd.
Episode 10 of CppCast with guest Roland Bach recorded May 5th, 2015.
In this episode, we talk about some C++ compiler news from Microsoft Visual C++ and GCC.
Then we'll interview Roland Bach about SQL++11,
a type-safe EDSL for SQL queries in C++.
Roland talks about some of the unique challenges he faces with SQL++11
and what he hopes to see in future versions of C++.
Welcome to episode 10 of CppCast, the only podcast for C++ developers by C++ developers.
I'm your host, Rob Irving, and I'm joined today by my co-host, Jason Turner.
How are you doing today, Jason?
Good. How are you doing, Rob?
Doing good. Still recovering from getting back from build.
Sorry, what were you going to say?
You had a good time, I take it?
I did have a good time. I made a couple connections for possible future guests.
Notably, I talked to Jim Radigan, who's on the Visual C++
compiler team, and he gave a great
session about code generation.
So I hope to have him on in a couple
weeks. And
made a couple other contacts, too, and
I'll definitely be reaching out to them for future
episodes. Excellent.
Yeah. I also want to start off the episode by thanking Hartmut Kaiser for joining us for Episode 9.
It was a really great episode.
We talked about asynchronous programming and the HPX library that he works on.
So you should definitely go check out that episode if you haven't already.
I want to start off the episode by reading a piece of feedback.
This comes in from Victor.
And Victor writes in,
First of all, congrats on CppCast.
I think that what you started here is great.
Keep up the good work.
Second, I was just curious if you have tried
to arrange an interview with Sean Parent.
I have seen several talks of him on YouTube,
and he has some interesting ideas
regarding software development in C++,
and I think he's been working recently on a book. In my opinion, he would be a great guest. And just so you know,
I've enjoyed each of the podcasts so far. So I don't think I'm familiar with Sean Parent.
Jason, are you familiar with him? I am definitely familiar with the name.
I think I've seen one of his talks before, but I can't remember exactly.
Okay. Well, it sounds like he would definitely be a good
guest i'm curious what the book is that he's working on so i'll have to try to reach out to
him to see if you've been interested in coming on the show so joining us today is roland bach
roland is the head of development at p pro financial Limited, an FCA-regulated e-money institute
offering prepaid MasterCard card programs
and comprehensive financial solutions
for international electronic payment transactions.
Since 2008, he's been using SQL and C++.
Being unhappy with the string-based approach
of most SQL libraries,
he decided to do something about it
and developed a type-safe EDSL for SQL and C++
called SQLPP11.
In his spare time, Roland is working on SQLPP11, experimenting with Concepts Lite,
and trying to write a proposal about compile-time configurable names for C++ standard.
He lives and codes in Munich, Germany.
How are you doing today, Roland?
I'm doing fine. How are you?
Doing really well.
Okay, cool.
I have a couple news articles to start off the episode.
First, a few from the Microsoft Build Conference from the Visual C++ team.
The first one is this link about...
It's just basically an updated table of the C++ 11, 14, and 17 features
that are available now in Visual Studio 2015.
And notably, they recently brought in const expression support,
but they're still missing expression Sfinay.
Have you guys had a chance to take a look at this?
Yeah, I took a look at the list,
and, well, as a library developer I have to say it's about time.
Because people are asking for Visual Studio support for libraries like SQL++11 and I just can't give it to them.
There's just no way. And I'm not even sure that the current release will be sufficient.
I had a contributor for a question who tested with the latest preview release,
and that just didn't compile because constexpr support is, as you can see in the article, is still partial.
And I think there's some stuff missing that I'm actually using in the library.
Yeah, and I wasn't really sure what they meant by partial support. I don't think they went into
detail on that in this article, but you're saying that it is still causing some issues for you? Well, at least in the latest preview,
this guy tested with C2P6,
which is probably very close to the current release.
Okay, well, there's a new RC,
so maybe that's been resolved.
I actually tested with my library with the RC
and also still saw problems with constexpr in my uses.
I think it was complaining about returning of a const reference type from a constexpr,
which I don't know if I'm doing anything wrong there,
but it's been working with Clang and GCC for several years.
Yeah, I have a similar situation.
I'm using constexpr character arrays. And those are working
outside of
structs fine with the compiler, but as
soon as I put it inside a struct, then
it complains about this not being
constexpr. So I'm not
a standard expert, but
I think it's wrong because other
compilers accept it.
What about
expression Sfinet?
Is that a problem for you as well?
Or is that something you're not using?
I'm not 100% sure if I'm using it,
so I can't really comment on that.
Okay.
So the other article here is really just kind of an overview
of the constant expression support in Visual Studio 2015 RC.
It does say RC.
I wasn't aware that they put it into CTP6, so maybe there are some differences.
But I guess if Jason's still hitting some problems, then they definitely need to still do a little bit more work on that. And then this other article is about resumable functions in C++, which is something
Microsoft is proposing for the C++ 17 standard. And they've actually already gone ahead and put
it into the visual C++ compiler for this latest version. So what do you guys think about the
resumable functions? I thought they're pretty interesting. Yeah, I've been programming in C++ for so long
not having something like a resumable function
that I personally have a hard time thinking,
okay, exactly where am I going to utilize this?
But I'm also excited to see it coming in.
Yeah. How about you, Roland?
I have no use case for it,
but it's very good to have this in the language
because all the examples that I saw before look really, really scary
when people try to work around and do some weird long jumps or I don't know what.
Right.
And then the next article I have to break away from the Microsoft Visual C++ stuff
is actually coming from GCC, and they have released version 5.1,
which now has full C++ 11 and 14 support.
So that's good to see.
And this makes them the second compiler
to have full C++ 11 and 14 support.
So great to see two fully compliant compilers
in Clang and GCC.
Yeah, absolutely.
It's really good to see that the standard is implemented so quickly by some compilers.
Yeah.
I wonder why they don't use C++11 as a default now.
I was curious about that.
Yeah, at the top of the article it says they're still not setting it as the default.
Are they just worried about breaking existing projects?
I mean, you know, if you go from compiling to 98 to 11, you're not going to lose anything.
So I'm not sure why they would not use 11 as the default.
Yeah, and theoretically you get a performance boost if you can enable some move operations.
Right.
And it doesn't really say that in the article.
I guess we just have to ask someone who works on GCC
to find out an explanation for that.
Yeah.
Yeah.
I mean, it's a tough decision.
Because, well, you never know what you might break.
Some keywords behave slightly different.
Something might emit warnings now that didn't emit warnings before,
like autopointer is now deprecated and you have a warning there.
If you compile with warnings as errors, then you break a project.
Yeah, that's true.
Well, let's start talking about your stuff, Roland.
There's quite a few C++ libraries for interacting with SQL databases.
Why do you think we need another one?
Well, I started using one of these other libraries, several in fact, when I started programming C++
for the first time and I got introduced to all these cool features that
Compilerd can do. And when I was working with SQL in C++, it turns out that I made so many stupid mistakes, like typos. Columns were
written in the wrong way. Or if you analyze the results of a select statement, then you have maybe
an index-based approach, maybe using the wrong index because somebody changed the table
layout and suddenly columns appear at a different index. It's a
maintenance nightmare in some cases. Or database specific things that go into
strings where you don't know if you migrate to another database whether your
strings are still correct.
So you have all this structure in SQL statements,
and you have this all in your mind,
and maybe you even draw it on a picture,
and then you create a creator from it.
And what you do in most libraries is that,
well, you just put it into a string,
and then it's just a sequence of characters with no structure at all in the compiler,
cannot tell you anything about it.
Right.
So at that time, I thought, well, okay, let's try something different.
Let's try to, and I didn't know the term at the time, but let's try to write an embedded domain-specific language for SQL in C++, so that I can express the structure of SQL queries in expressions in C++.
And that is what SQL++11 is doing.
It's, I don't know, the third or fourth generation of my attempts to do so and with C++11 I'm
now able to do most of the things that I want to do in this library. So the
idea is that you tell the compiler about the structure of your database and
tables and columns. You tell them about the names
and the value types. You tell it about whether something is read-only or
whether you can write to it, stuff like that. And you also give it in the
form of the library an instruction set or an embedded domain specific language to teach it SQL basically.
And then you can use this language in C++ to construct your queries as normal C++ expressions.
And the compiler, equipped with all this information,
so the information about the tables and the columns,
as well as the workings of this language,
is able to detect all kinds of bugs for you.
So these typos that I talked about earlier,
of course, since columns are now members of tables,
data members of tables, the compiler will detect typos immediately.
Also, if you're comparing apples and oranges, so you, I don't know, compare a string column to an integer,
it will tell you because it knows that this column is of a string type. It goes so far that it analyzes the structure of the query and will figure out that, for instance, you're using columns in your query that
are not from any table that you use in the from, for instance, in the select statement.
So you select something from table A and say from table B, then the
compiler will tell you. In a similar way, it helps you analyzing the
results. So results of a select statement, for instance, are based on types of the compiler constructs
from the query, which have data members which represent the individual columns that you
selected.
So, if you select, I don't know, something called A and something called B, then the
result object or the result row object will have data members called A and something called B, then the result object or the result row object
will have data members called A and B.
So you have no way of bypassing this by accident
because the compiler will tell you
if you're addressing something with C,
and that's not there.
Right, and the other SQL libraries in C++
would be returning string data.
Is that right?
Well, yeah, they typically would be returning string data
and the access to those results would be similar to a map.
So you would access a column by its name,
but the name would not be on C++ language level, but instead be a string,
typically, or an index.
And with SQL++11, you can have these result columns with a name that is known to the compiler,
and then you cannot mistype it without the compiler knowing.
Or you cannot have name clashes, for instance,
because the compiler, again, will tell you that you have two columns called A,
and then it will tell you that, well, this doesn't compile,
and in other libraries you might then have difficulties in understanding
what happened when you access column A,
and the library just chooses one of those.
So I would imagine that you're adding some compile time overhead compared to just like a plain string access model like you're comparing it to.
But I would also imagine that maybe this saves some development time because you spend less time tracking down runtime errors.
Is that what you're finding?
Yes, absolutely.
So when we introduced this to our team and to the team I worked in before, it really changes the way that you work with SQL in C++ because you have to test much less
because you cannot make all the stupid mistakes.
You don't have to test that your query is syntactically correct, for instance,
because the compiler and the library will take care of that.
So you can really focus on the logical errors
which of course you can still make
so
the library has no way
of thought reading
currently
That's in the next version, right?
In the next version, yeah, C++17
will probably support that, I think
No, honestly
it really changes the way that you develop SQL applications in C++
because you don't make as, or if you're a person like me who does many of those really stupid mistakes,
then you won't do those anymore.
And they won't hit your test environment and they will not hit your live environment.
So if you don't have 100%
test coverage,
well, be
happy to use this library because
it will protect you from a lot
of stupid things.
So what's the process
like if I'm introducing
SQL++11 to
a new application or a new database?
Do I need to write a whole bunch of structs or classes to represent my database objects
and the different rows and columns and all that?
No, the typical approach, at least in my experience, it's to use a script. And there are example scripts that come with the library
that you use to generate these header informations
out of your database definitions.
So, I mean, if you have an SQL application,
then you have database definition language files laying around
that describe what your database looks
like. And you translate those typically also in the make file, so that
if you change the database definition then that your code changes. But you
translate those in at compile time or right before compile time into header files,
and these are then used in your source code.
Okay.
Does that make sense?
Yeah, that sounds powerful.
I was wondering if you had a script or if you had to do it manually,
but having a script sounds great,
and you can use that to update as your database changes, right?
Yeah, right.
So that's the typical approach.
I know that some people do it differently.
I'm not exactly sure how their process works,
but one contributor is using Boost preprocessor library
to basically generate another small language to write these table
definitions in C++. Looks really cool. I'm not sure what the exact
process is. Mine is based on that the database is basically the
utter truth. The database is correct,
and the C++ code has to behave accordingly.
So that's why we're using the code generator approach.
Right.
So there are a lot of different implementations of SQL.
What SQL databases does SQL++11 work with currently?
Well, SQL++11 has no idea of database
instances itself.
So it's
completely
unspecific for databases.
But there are connector
libraries, and
for each database instance or vendor, you would have to write a connector library.
And there are currently connector libraries for SQLite, for MySQL and MariaDB and for Postgres. And these connector libraries not only serve the purpose of
doing the actual interaction with the database,
but they also can
introduce database-specific things to the library.
So, for instance,
they can turn off certain features at compile time.
Oh, okay.
For instance, SQLite doesn't have auto-join.
They have write auto-join, but they don't have the full auto-join.
So if you're using that in your code,
and maybe you're coming from a different database,
and now you want to migrate to SQLite,
then the compiler will tell you at compile time that, hey, you cannot use auto-join with SQLite because it's not supported.
That's really powerful.
Is SQLite, is that a newer database format for SQL++11?
Because I don't recall seeing that in the documentation
when I was looking into it the other day.
No.
That one's been around? Okay.
Yeah, at least since summer since last year, I think.
Okay.
What's the future look like
for SQL++11?
Is it still being actively developed?
Yes, it's actively being developed.
There are lots of feature requests
which I'm trying to
fulfill, like, for instance, new types.
The most important one would be about dates and times.
Currently, all the code that I'm involved in is using Unix timestamps,
so we're using longs for representing days and times, but
obviously others don't do that. So, there is a requirement for supporting at least
date and times. There are other things that I would like to add, like
conditional result columns. That is, everything that I described so far is
very much true for static queries, when you know exactly what
the structure of your query is. If you don't know 100% ahead what the structure
is, but maybe some columns which might be expensive to
select are only chosen at runtime, maybe by using some input from a user,
then currently you can do this by falling back to this map approach of
other libraries, but it would be possible to use something similar to the case if statements in SQL
and do something similar in C++ in the library to say,
okay, if this condition is true, then return a value with this name and this type,
otherwise return null, something like that. So in this way, I could
add conditional result columns, which would preserve all this name and type safety that
this library is all about. In addition, something similar for joins, currently you can add conditional columns to a query or
you can add conditional conditions to a where thing. That really depends on
runtime user input. But currently you cannot do, I don't know, write out a join
conditionally. Either you do it or you don't.
That is... So the library is not complete and I
want to add those things.
Also there are requests which
are related to
the things that we talked about in the introduction
and that you talked about
last week with
Heartboot.
About asynchronous SQL.
So that you fire a query and then you have a contingency with a then or something like that
to handle results when they actually return
and do something different in between. You might also want to do this with
individual rows because maybe not only the result takes time to calculate for
the database but it also might take time to transport individual rows over the network, for instance.
And then, well, there are upcoming new standards.
So there's not going to be an SQL++14,
because that standard doesn't really give me features
that would change the world for the library.
But with C++17 and Concept Slides, for instance,
I would probably fork the library and do something new.
Because, well, then it would allow to make the code much more expressive
and easier to read, easier to maintain, as it currently is.
Sure. Do you want to talk some more about ConceptsLite?
Because you told me before the show that Andrew Sutton's actually been doing a lot of testing
with SQL++11 as kind of a testing ground for Concepts Light.
Yeah, well, I'm kind of forcing him to.
No, we met at CppCon last year,
and he saw one of my slides which says,
I'm so looking forward to Concepts Light.
Asked me about it, and, well, we got to talking
and figured that, well, yeah, it might be a good experiment
to migrate SQL++11 to Concepts Lite.
And a few months back, I started to do so.
But the thing is that the constructs in this library
are pretty complicated and pretty challenging to compilers.
And I don't know, I have variadic CRTP, which sounds horribly.
And it is kind of... I'm using that. So it's not only CRTP, which in itself is a weird construct, but you could of course do CRTP with multiple base classes, but you could also use template
arguments and, in my case, variadic template arguments to do CRTP with.
So I'm using variadic CRTP and then the base classes again have templated functions, and if you
combine all that with concepts,
it's
very, very easy
to crash the compiler as
it currently is.
The current concept light
implementation is based on
GCC 5.0,
and that one compiles the library with no problems.
But as soon as I start saying,
okay, from functions, for instance,
can only take table arguments
and all table argument names have to be different,
this combination just crashes the compiler.
So as I understand concepts and concepts light,
it's mostly about placing some compile time restrictions
on what types can be passed to your templates, right?
Right.
So do you hope to, I guess,
what, it'll clean up your error messages maybe?
Are you looking to gain anything?
Like what ultimately do you look to gain
by using concepts with your project?
Well, for once, the restrictions that you mentioned
are helpful in understanding the code, right?
So I can say, okay, I have a concept for tables, and I have a concept for tables and I have a concept for
uniqueness, which is saying that
all arguments in a variadic template list
have to be of unique type.
Oh, interesting. Okay.
I can use these to describe in the code that the from function only
takes tables and only accepts it when they are actually of
different type. It's a little bit more complex because when you have joins
then different arguments may represent several tables. But in
principle, you can use the concepts to describe what the
arguments should be for your meta functions. And so that is a huge gain of course. Then these days when you have a function
and you have template arguments to a function and you
figure out in the function, I don't know why a static asserts something that
something's not 100% correct, the arguments don't fit, then you hope to
see a nice static assert message. But maybe you also have a
static assert in the return type, very likely, and then currently you're
getting horrible error messages from the compilers because they cannot really figure out what the return type is.
Then you get all kinds of crazy crazy stuff. And with concepts, that is a
relatively new development and I'm very glad that it came out this way. If a function does not meet the concepts,
then the return type isn't evaluated anymore.
That is really, really helpful
because now I don't have to code around this.
Okay.
I want to interrupt this discussion for just a minute
to talk about this special offer that JetBrains has made
for CppCast listeners.
JetBrains makes some awesome tools for C++ developers
in any environment.
There's the ReSharper C++ plugin for Visual Studio developers,
AppCode if you're working on iOS or OSX apps,
or their new cross-platform C++ IDE, C-Lion,
which runs on Linux, Windows, and OS X apps, or their new cross-platform C++ IDE C-Lion, which runs on Linux, Windows,
and OS X. JetBrains is offering a coupon code, which can be used to get a personal license to
any of those tools for 25% off. The code is cppcastjetbrainscpptool. All one word,
just enter that code during checkout where it prompts you for the discount code. Again, that's CppCast JetBrains CppTool, which will get you 25% off any of JetBrains C++
tools, CLion, AppCode, or ReSharper C++. I was told this coupon will expire on May 17th,
which is just 10 days away, so don't let it go to waste.
So before we move on from SQL++11, I just wanted to go over again how amazing the syntax looks to use this. I'm looking at some of your examples on GitHub, and you just have this database connection object and a table, which in this case is called
foo. And you just do db select foo.name, foo.hasfun.fromfoo.where foo, and some ID check.
And I'm just trying to think of, and this is in a for-each loop, so it returns a list of rows that you're going to iterate over.
And I'm trying to think of what that would look like in some other SQL library.
And there'd be a lot more work just to be able to parse over all those results.
Is that right?
Well, it depends a bit on your setup.
If you really just have a static query and you don't have real arguments from the outside world,
then you would basically just write a string with exactly that query.
It becomes more interesting if you have input from the outside world
and you need to make sure that there is no code injection.
It becomes more interesting if the project lives
and the database migrates or is changed in some way,
and your table definitions change,
and you add more columns or you remove columns.
In those cases, the string-based approach,
which, of course, compiles faster and is easier to implement
for a library developer,
those things, well, they come back to bite you.
Okay.
And with SQL++11, it's, well, you can still write the query more or less like SQL.
It looks almost like SQL.
Anybody who can understand SQL can also read this.
Also, if queries become more complicated, so if you have
sub-queries, you could have a select and use that as a
pseudo table in your from in the main query.
It's becoming hard to read.
If you have large queries and you write those in SQL,
well, it's not so easy to understand anymore.
With SQL++11, you can break this down.
You can just construct your subquery first, put it into a variable.
You don't want to write the type, but you can use auto, of course.
And then just put this variable and use it as a table in your main query. So then you can break it down into pieces which are easier to understand and easier to maintain.
Very cool.
A few months ago, you also gave a talk at the Meeting C++ conference
about pruning template error messages.
Did this talk come from the work you've been doing on SQL++11?
Yes, very much so.
The SQL++11 library is heavily templated, of course, because otherwise you couldn't do all this seemingly magic stuff.
And at first, the template error messages were just horrible when I first started in any of these heavily templated libraries. But I stumbled over an article by Eric Kneebler saying that, or the title was, Why Template
Error Messages Suck and What You Can Do About It.
And that was very inspiring. and it pushed me in trying to reduce the amount of template error
messages that you get from SQL++11 if you're doing something wrong.
Because, I mean, the compiler has to tell you that you're doing
something wrong and it doesn't really understand SQL, of course. It only
understands that you're doing something wrong within this embedded domain specific language. So there are several techniques that you
can use, of course, and this article is going through techniques that are
used in the library. One is, of course, course helping compiler vendors which we talked about before,
like supporting Andrew Sutton and writing the demo implementation for
Concepts Live, for instance. Because compilers make a difference.
Anybody who went from GCC to Clang a few years ago noticed that immediately that compilers make a difference.
GCC caught up now quite a bit.
Then there are other things like you want to avoid recursion because if you have a recursive process in your meta program and something happens deep down in
your recursive function, then the compiler will basically tell you all
the different steps in your stack. So trying to avoid recursion, that is a very powerful tool. Many things
in current standard development are addressing these, like the fold
expressions that are by Richard Smith and Andrew Sutton, for instance, or in C++14, there are these
index lists or index generators, I'm forgetting the name. Those are all aimed at
trying to reduce the amount of recursion that you have to do when
dealing with Veridict templates. And the other thing is that, similar to the idea in++11, then maybe only in the
300th iteration in some template metamagic you realize that, oh damn it,
there's something wrong here. The user supplied the wrong type. It doesn't have
a member called ID or something like that, well it doesn't help to
report a problem there in that code because you're
deep down inside your code and the compiler will basically have to report
all this stuff. So what you do is you try to detect the problems or you try to check arguments
against the requirements as soon as possible. So basically as soon as
you're inside your code, the first thing you have to do is check the arguments of
the user. And as Eric remarks in his article several years back, that is
best practice in any coding, but somehow people tend to
forget that when they're doing templates. Maybe it's because templates
are so complicated and you're just focusing on getting it right anyway. But yeah, it's
really changing the way that
people use these libraries.
They are not afraid to make mistakes anymore
when the number of error
messages that they get
is reduced by a huge
amount. And you can bring error messages
down by factors of 100
easily in many cases.
I'll have to find that article from Eric Niebler and put it in the show notes. It sounds like a really good read. down by factors of 100 easily in many cases.
I'll have to find that article from Eric Niebler and put it in the show notes.
It sounds like a really good read.
I'm not sure if it's really online
anymore. Last time I looked for it,
I only found it in
archive.org.
But it's a nice
thing.
One last thing. I watched
a lightning talk that you gave at CppCon last year where you discussed your
wish list for C++.
And one of those was making names configurable via templates.
Could you explain that and what some of the benefits would be?
Okay.
Well, the idea, of course, comes again from the library where I'm using names all over the place.
And it's very hard to construct these types that I talked about earlier. When
you want to construct a type for a result, for instance, that contains members
which names depend on the names of the columns in some
expression and the compiler has to calculate this type
based on the expression. And also you
want to do... and variety composition requires that you have to have the
ability to give names to the members that you use in the composition because
otherwise, well, how would you address them? And the idea is that, well,
everything in, well, at least every L value in C++ has a type, a
value, and a name, but in templates we can only use types and
values for configuration of templates or template parameters. It
would be great if you could also define names and then use these names, for
instance, as the name of a member that you have in your template. So one
of the applications would be a named tuple. I mean, tuples are great, but you can
access the data members of a tuple only via an index or in C++14 with a type, if the type is
unique. Well, that's fine for metaprogramming. It works wonderfully. But as soon as you give a tuple to a user of your
library, well, it feels kind of weird, right? Because again, they have to use
indexes and you cannot really iterate over it with a normal for loop or
something like that because it's weird. But if you had a named tuple, then you could construct something on the flight while compiling
that has an arbitrary number of members,
like a tuple with arbitrary types and arbitrary values,
and it would behave just towards the user,
just like a normal struct.
Right. Yeah. That would be great and I'd really like that of course, especially
for my library, but you could use it for all kinds of interesting things. So, for
instance, all users of CRTP that I have could be replaced by using something similar and which wouldn't
require inheritance like CRTP. CRTP uses inheritance and this is weird in itself
because it doesn't implement something like isA, but in most cases that I'm using CRTP, you're adding functions to the
derived class and what you could do if you had names is that you could create
data members of a callable type which would behave just like a function
that you inherit from CRDP without inheritance.
Does that make sense?
Yeah, definitely.
Are you working on a proposal or anything
for a future version of C++ to have this?
I'm hoping to do so in the future. I've wrote a mail to the C++ standard proposal list,
and the feedback that I got was very good.
I had an open session at CppCon last year with lots of visitors,
and again, the feedback was very positive to this.
Gave a talk in Munich recently, and yes, it's interesting to see that,
and I would really like to have this in the language.
It could be used as a counterpart to what Reflection is currently
doing. Reflection is more about the analysis of types and giving you
means of compile time to report, I don't know, member names for instance. If you
had names and would be able to use those as template arguments,
then you can also use those to construct types from it.
So that would be a nice pair.
Yeah, that could be some crazy powerful capability there. When you mentioned earlier that you use variadic CRTP,
I couldn't quite piece together how you were using it,
but now with the background for
wanting to template the types of names, excuse me, it's coming together. I understand
how you used CRTP to kind of work around that limitation.
Yeah, I'm also using it for the expressions. So there's one type, one variadic template for all
expressions or statements in SQL and it can be configured by basically saying
what clauses are allowed in a select statement, for instance, and the
clauses are types that contain templates, which can then be used in
a variadic CRTP to imbue the derived statement class with all the functionality that comes with
the from and where and having and so on. You make me totally curious now. As a library writer myself,
I mean, what you're talking about implementing,
what you're doing has to be a big load on the compiler.
Do you have users complain about compile time?
Well, users always complain about compile time. complain yes it puts a heavy load on the on the compiler but I know if you if you check out the library there are lots of examples in there it it compiles on my
machine in a few seconds okay so it's not it's not terrible. Right. So if you compare it to,
I don't know,
what's the worst example that I can think of?
Sorry for the developers,
but Boot Spirit, for instance,
that is painfully slow,
or at least it was the last time I used it.
It's not even close.
Okay.
And having longer compile time in favor of, you know,
fewer runtime errors is definitely preferable.
Stal, I 100% agree.
I'm just curious.
Since it's an open source library,
I'm sure you get lots of feedback.
Yeah.
Well, in the feedback on GitHub, for instance,
or from email lists i have i have no
complaints about compile times oh okay very good my co-workers sometime but um you have many reasons
why it was slow and if you don't mind if i take a step back for just a second uh i'm just curious too like if you notice like um is using uh your library uh better
performance same performance or different from you know making sql queries directly jason i think we
lost you for a second if you want to repeat the question oh i'm sorry i was wondering if uh your
library is faster or better or different than in performance,
runtime performance, than using SQL queries directly.
I admit that I haven't made definitive measurements yet, but I see no real reason. There might be
differences depending on the use case. The library assumes that you're
actually going to use all the columns that you select. Okay. So it does all the type conversion
when it constructs the row.
Okay.
Well, yeah, I mean, if you haven't noticed a difference
and you're using this in production,
then I would say there's probably not a big difference.
Just curious.
Yeah, not a big difference, no.
Okay.
So, Roland, is there anything else you want to go over before we let you go?
Just wanted to mention that when we talked about the names thing and so on,
one of the crazy ideas about SQL++11
that I think Eric Niebler gave me on the boost development list is it would be cool to use this library also for non-databases
or not the typical databases,
but you could also use something like this on vectors or sets
or, I don't know, on streams with normal structures in it.
There is a prototype for that,
and you can actually, with a certain struct,
use SQL queries to insert these structs into a vector and select from it.
That works wonderfully fine.
I'm currently not developing this any further
because of the ideas that I had with names. If we had the abilities from
what the reflection group is planning and combine that with names, then it would actually be possible to use
vectors of structs or sets as your tables in a normal database.
And that would be easy to compile. Currently it's a lot of overhead
because you have to use a code generator again to create these structs,
and then could only use SQL queries for exactly those structs they use in the code generator.
But in the future, since the compiler knows all the names and types of structs anyway,
if we had reflection and names, then we could use SQL queries on our normal containers without any problems.
That's very interesting.
Yeah, definitely.
So where can people find you online, Roland?
Well, the easiest thing to do is to search for my name and maybe SQL++11 or just my name and c++. If you just look for my name, you get
a very old wrestler from 50 years ago. So, on GitHub, I think that's the easiest way
to do it. Great. And my email address is there. And if you have an account on github you can use the github issues
to get in touch with me
and that's github.com
slash rboc
right
okay thank you so much Roland
thank you
it was a pleasure
thanks so much for listening as we chat about C++
I'd love to hear what you think of the podcast.
Please let me know if we're discussing the stuff you're interested in,
or if you have a suggestion for a topic, I'd love to hear that also.
You can email all your thoughts to feedback at cppcast.com.
I'd also appreciate if you can follow CppCast on Twitter,
and like CppCast on Facebook.
And of course, you can find all that info and the show notes
on the podcast website at cppcast on facebook and of course you can find all that info and the show notes on the