How to deal with Java's reserved keywords [Was: Transpose]

93 views
Skip to first unread message

Lukas Eder

unread,
Jun 22, 2013, 8:00:08 AM6/22/13
to jooq...@googlegroups.com, Christopher Deckers
Hi Christopher,

2013/6/22 Christopher Deckers <chr...@gmail.com>
Hi Lukas,
 
The CASE expression is indeed modeled by DSL.decode(), as you can see here:

"Unfortunately, both case and else are reserved words in Java. jOOQ chose to use decode() from the Oracle DECODE function, and otherwise(), which means the same as else."

I think keywords should not be replaced with synonyms, otherwise you are not mapping SQL to Java, but SQL to a jOOQ-specific QL. I think that even if it is not as good as having "case()" and "else()", there should be "case_()" and "else_()". Developers would understand that this is because of reserved keywords and would not have to analyze the API/documentation to map their SQL.


We are lucky that Java does not have more reserved keywords, otherwise:
SELECT * FROM BOOK WHERE PUBLISHED_IN = 2011 ORDER BY TITLE
would have been:
create.pickFrom(BOOK).condition(PUBLISHED_IN.sameAs(2011)).sortBy(TITLE)

:)

Grrrr ;-)
But in a way, you are right of course. First off, let's look at the various reasons why jOOQ cannot map SQL to Java 100%:

1. "Keywordless" syntax (e.g. SET a = 1, b = 2)
2. "Semantic" whitespace (e.g. ORDER[ ]BY)
3. "Superfluous" keywords (e.g. CASE ... END)
4. "Superfluous" syntactic elements (e.g. WITHIN GROUP (ORDER BY..) OVER (PARTITION BY..)
5. Java's reserved keywords
6. Java's missing operator overloading capabilities
7. SQL's "reference before declaration" capability

How does jOOQ work around the above?

1. By introducing artificial keywords. Examples

SQL: UPDATE t SET a = 1, b = 2
jOOQ: update(t).set(a, 1).set(b, 2)

Note that this example also shows missing operator overloading capabilities, where "=" is replaced by ","

SQL: (a, b) IN ((1, 2), (3, 4))
jOOQ: row(a, b).in(row(1, 2), row(3, 4))

In this case, ROW is an actual (optional) SQL keyword implemented by at least Postgres

2. By using camel case

This is actually very simple to work around. jOOQ follows standard Java method naming conventions to map SQL keywords (case-insensitive) to Java methods (case-sensitive, camel-cased)

SQL: ORDER BY
jOOQ: orderBy()

3. By omitting them

Some SQL keywords aren't really necessary. While in SQL itself, it is easy to write them, writing them in Java is a bit more tedious.

SQL: CASE .. WHEN .. THEN .. END
jOOQ: decode() .. when(.., ..)

Agreed, this goes along your argument and should probably be fixed. jOOQ currently omits THEN and END keywords, here.

4. By omitting them

Some SQL constructs are hard to map to Java, but they are also not really necessary

SQL: LISTAGG(a, b) WITHIN GROUP (ORDER BY c) OVER (PARTITION BY d)
jOOQ: listagg(a, b).withinGroupOrderBy(c).over().partitionBy(d)

Alternatively, of course, jOOQ could introduce:

listagg(a, b).withinGroup(orderBy(c)).over(partitionBy(d))

Creating reusable orderBy(...) and partitionBy(...) clauses. This has to be well-thought-through, though

5. By using an alternative

This is the point of interest in this discussion. Currently, there are collisions between:

SQL: CASE
jOOQ: decode

SQL: ELSE
jOOQ: otherwise

SQL: FOR (in PIVOT clauses)
jOOQ: on

Future collision potential:

SQL: BOOLEAN, CHAR, DEFAULT, DOUBLE, ENUM, FLOAT, IF, INT, LONG, PACKAGE

6. By using descriptive methods, or a comma

Most SQL operators have to be mapped to descriptive method names in Java:

SQL: =
jOOQ: equal(), eq()

SQL: SET a = b
jOOQ: set(a, b)

SQL: <>
jOOQ: notEqual(), ne()

7. That cannot be worked around

This is what has been keeping me from implementing CTE so far.

SQL: WITH a(x, y) AS (SELECT 1, 2) SELECT a.x, a.y FROM a

Discussion

As you can see, there are a lot of caveats when implementing an internal domain specific language (as opposed to an external one). As you stated yourself, luckily, Java doesn't have too many reserved words. I currently see four ways to solve 5)

a) by using synonyms
b) by appending "disambiguators" such as case_ or case$ or case
c) by introducing artificial spelling, such as casë, casǝ, casɇ ;-)
d) by changing the API to be all-uppercase: SELECT(), CASE(), ORDER_BY()
e) by changing the API to be camel-case with an upper-case initial letter: Select(), Case(), OrderBy()

d) and e) are massive changes. Any other ideas?

Cheers
Lukas

Roger Thomas

unread,
Jun 22, 2013, 9:19:19 PM6/22/13
to jooq...@googlegroups.com, Christopher Deckers
I have to say, if you were to change things to get around reserved words I would vote for d (all-uppercase).

The logic is no more than - this seems to be the way people have/do write SQL queries. I can't say its part of any standard, but it does seem to be the convention and its one I've been following for rather to many years. It maybe just because I and SQL come from an age when uppercase was use in languages such as Informix 4GL :)

One thing, all the background info you have provided would fit rather well in the main jOOQ document - under some form of background or why it is as it is heading.

Roger

Lukas Eder

unread,
Jun 23, 2013, 4:24:14 AM6/23/13
to jooq...@googlegroups.com, Christopher Deckers, Roger Thomas



2013/6/23 Roger Thomas <rithom...@gmail.com>

I have to say, if you were to change things to get around reserved words I would vote for d (all-uppercase).

The logic is no more than - this seems to be the way people have/do write SQL queries. I can't say its part of any standard, but it does seem to be the convention and its one I've been following for rather to many years. It maybe just because I and SQL come from an age when uppercase was use in languages such as Informix 4GL :)

.... and FORTRAN, COBOL, BASIC, I remember those days. Pascal and C really messed up our upper / lower casing universe! ;-)

d) has its "extreme cases" as well, such as:

- ON_DUPLICATE_KEY_UPDATE()
- WHEN_MATCHED_THEN_UPDATE()
- WHEN_NOT_MATCHED_THEN_INSERT()

The obvious advantage of making SQL DSL methods all-uppercase is the fact that they can be immediately distinguished from non-DSL methods, such as:

- a.BETWEEN(b).AND(c)
- a.BETWEEN_SYMMETRIC(b).AND(c)
- a.IS_NULL()
- a.IS_NOT_NULL()
- ROW_NUMBER().OVER().PARTITION_BY(a).ORDER_BY(b)

as opposed to

- a.getName()
- a.getType()
- a.getDataType()

Maybe, both APIs could be maintained in parallel using a code-generator, leaving the decision up to the user, whether they want to camel-case or upper-case their SQL DSL. From a backwards-compatibility perspective, there's probably no choice in maintaining both in parallel anyway.
 
One thing, all the background info you have provided would fit rather well in the main jOOQ document - under some form of background or why it is as it is heading.

Yes, you're right. I had thought of this, yesterday. It's too bad to be "hidden" in an e-mail in the user-group. I'll document this with

With Christopher Decker's recent helping in creating a railroad-diagram tool [1] and Peter Verhas's inspiration, mapping a finite state-machine to a fluent API (and / or a BNF), the language-aspects of jOOQ will hopefully be heavily improved in the near future [3].


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

Lukas Eder

unread,
Jun 23, 2013, 4:34:34 AM6/23/13
to jooq...@googlegroups.com, Christopher Deckers, Roger Thomas



2013/6/23 Lukas Eder <lukas...@gmail.com>




2013/6/23 Roger Thomas <rithom...@gmail.com>
I have to say, if you were to change things to get around reserved words I would vote for d (all-uppercase).

The logic is no more than - this seems to be the way people have/do write SQL queries. I can't say its part of any standard, but it does seem to be the convention and its one I've been following for rather to many years. It maybe just because I and SQL come from an age when uppercase was use in languages such as Informix 4GL :)

.... and FORTRAN, COBOL, BASIC, I remember those days. Pascal and C really messed up our upper / lower casing universe! ;-)

d) has its "extreme cases" as well, such as:

- ON_DUPLICATE_KEY_UPDATE()
- WHEN_MATCHED_THEN_UPDATE()
- WHEN_NOT_MATCHED_THEN_INSERT()

The obvious advantage of making SQL DSL methods all-uppercase is the fact that they can be immediately distinguished from non-DSL methods, such as:

- a.BETWEEN(b).AND(c)
- a.BETWEEN_SYMMETRIC(b).AND(c)
- a.IS_NULL()
- a.IS_NOT_NULL()
- ROW_NUMBER().OVER().PARTITION_BY(a).ORDER_BY(b)

as opposed to

- a.getName()
- a.getType()
- a.getDataType()

Maybe, both APIs could be maintained in parallel using a code-generator, leaving the decision up to the user, whether they want to camel-case or upper-case their SQL DSL. From a backwards-compatibility perspective, there's probably no choice in maintaining both in parallel anyway.

Created a new issue for jOOQ 4.0, to keep in the back of our heads:

If the two APIs can be maintained in parallel, the change might also be introduced in a minor release in 3.x

Lukas Eder

unread,
Jun 23, 2013, 7:07:46 AM6/23/13
to jooq...@googlegroups.com



2013/6/23 Roger Thomas <rithom...@gmail.com>

I have to say, if you were to change things to get around reserved words I would vote for d (all-uppercase).

The logic is no more than - this seems to be the way people have/do write SQL queries. I can't say its part of any standard, but it does seem to be the convention and its one I've been following for rather to many years. It maybe just because I and SQL come from an age when uppercase was use in languages such as Informix 4GL :)

One thing, all the background info you have provided would fit rather well in the main jOOQ document - under some form of background or why it is as it is heading.

This is now added to the 3.1 manual:

Cheers
Lukas
 

--

Christopher Deckers

unread,
Jun 23, 2013, 12:51:53 PM6/23/13
to jooq...@googlegroups.com
Hi Lukas,

While not very active, I did keep an eye on this discussion, and I too found your answer to be very valuable. I am glad to see it making it somewhere in the manual.

Languages have reserved keywords, so mapping a language to another is likely to clash on some reserved keywords. The amount of clash depends on the languages that we consider and tricks we can apply. One consideration is about the target languages: should we have the same considerations for jOOQ used in Java and jOOQ used in say Scala? I will use "Scala" as a generic way of saying "other languages" throughout the discussion. Of course I understand that jOOQ's primary target is Java, but I am curious.



1. By introducing artificial keywords. Examples

SQL: UPDATE t SET a = 1, b = 2
jOOQ: update(t).set(a, 1).set(b, 2)
Note that this example also shows missing operator overloading capabilities, where "=" is replaced by ","

Would jOOQ on Scala be able to more closely match such construct if one wanted to?
 
 
SQL: ORDER BY
jOOQ: orderBy()

Would jOOQ on Scala be able to more closely match such construct? I guess that would mean having ORDER(BY(xxx)) and then BY could be problematic if used in other places.
  

6. By using descriptive methods, or a comma

Most SQL operators have to be mapped to descriptive method names in Java:

SQL: =
jOOQ: equal(), eq()

What is the rule with verbs? Should it be 3rd person, like "equals()" (if there were no collisions with Java's equals)?
 

SQL: <>
jOOQ: notEqual(), ne()

Would jOOQ on Scala be able to more closely match such construct?

 

7. That cannot be worked around

This is what has been keeping me from implementing CTE so far.

SQL: WITH a(x, y) AS (SELECT 1, 2) SELECT a.x, a.y FROM a

What is the problem with the above expression?

 
Discussion

a) by using synonyms

This is the worst suggestion in my view.
 
b) by appending "disambiguators" such as case_ or case$ or case

I don't mind hard rules, like "any keyword that may clash with Java keyword is going to be suffixed with '_'". I prefer suffix, because code completion would work when I start typing "case".

 
c) by introducing artificial spelling, such as casë, casǝ, casɇ ;-)

OK, this *IS* the worst suggestion :)
You forgot \uFF43\uFF41\uFF53\uFF45: case

 
d) by changing the API to be all-uppercase: SELECT(), CASE(), ORDER_BY()

My initial reaction was "ouch, this is ugly Java", but I do write SQL all caps, so having the DSL part be all caps to map SQL is really not that bad.

 
e) by changing the API to be camel-case with an upper-case initial letter: Select(), Case(), OrderBy()

This is odd, because it is neither the Java convention nor SQL.
 

d) and e) are massive changes.

Apart from being an incompatible API, what is the complexity? User manual mainly?

 
Any other ideas?

Apart from silly ideas like "cASE", not really :)

 
Cheers,
-Christopher


Roger Thomas

unread,
Jun 23, 2013, 6:03:57 PM6/23/13
to jooq...@googlegroups.com, Christopher Deckers, Roger Thomas


On Sunday, June 23, 2013 9:34:34 AM UTC+1, Lukas Eder wrote:


2013/6/23 Lukas Eder <lukas...@gmail.com>



2013/6/23 Roger Thomas <rithom...@gmail.com>
I have to say, if you were to change things to get around reserved words I would vote for d (all-uppercase).

The logic is no more than - this seems to be the way people have/do write SQL queries. I can't say its part of any standard, but it does seem to be the convention and its one I've been following for rather to many years. It maybe just because I and SQL come from an age when uppercase was use in languages such as Informix 4GL :)

.... and FORTRAN, COBOL, BASIC, I remember those days. Pascal and C really messed up our upper / lower casing universe! ;-)

It's odd, but I think Informix was mixed case, its just SQL was by convention uppercase. Having looked around a bit the old embedded SQL in C and SQLJ also followed this convention of SQL reserved words being upper case in a mixed case world. Its odd how such a hangover from the 80s can still be a strong convention now.
 
I presume to get the different styles of case (current, upper and camel-case) would involve writting each method in DSL.java 3 times over - each with the different name and each with it's own java doc.

Roger

Lukas Eder

unread,
Jun 24, 2013, 2:22:47 AM6/24/13
to jooq...@googlegroups.com, Christopher Deckers, Roger Thomas


2013/6/24 Roger Thomas <rithom...@gmail.com>

On Sunday, June 23, 2013 9:34:34 AM UTC+1, Lukas Eder wrote:
2013/6/23 Lukas Eder <lukas...@gmail.com>
2013/6/23 Roger Thomas <rithom...@gmail.com>

I have to say, if you were to change things to get around reserved words I would vote for d (all-uppercase).

The logic is no more than - this seems to be the way people have/do write SQL queries. I can't say its part of any standard, but it does seem to be the convention and its one I've been following for rather to many years. It maybe just because I and SQL come from an age when uppercase was use in languages such as Informix 4GL :)

.... and FORTRAN, COBOL, BASIC, I remember those days. Pascal and C really messed up our upper / lower casing universe! ;-)

It's odd, but I think Informix was mixed case, its just SQL was by convention uppercase. Having looked around a bit the old embedded SQL in C and SQLJ also followed this convention of SQL reserved words being upper case in a mixed case world. Its odd how such a hangover from the 80s can still be a strong convention now.
 
(hmm, I wrote this? :-) )
 
I'm not so sure about the convention. I'm actually used to writing SQL keywords in lower case while identifiers are upper cased. This convention helps visually distinguishing the two. Of course, you could do it the other way round to achieve the same goal. But in most databases, case-insensitive identifiers are actually upper-cased.
 
Anyway, identifier casing is an entirely other story...
 
I presume to get the different styles of case (current, upper and camel-case) would involve writting each method in DSL.java 3 times over - each with the different name and each with it's own java doc.
 
Yes, something along those lines. Or simply duplicating DSL. Or, duplicating the whole deliverable. Whatever solution is chosen, clearly, a code generator will do the tedious work. I have made good experiences with Xtend, which I'm using to generate the Row1..Row22 and related types.
 
Cheers
Lukas

Lukas Eder

unread,
Jun 24, 2013, 3:53:16 AM6/24/13
to jooq...@googlegroups.com, Christopher Deckers
Hi Christopher,

2013/6/23 Christopher Deckers <chr...@gmail.com>
Hi Lukas,

While not very active, I did keep an eye on this discussion, and I too found your answer to be very valuable. I am glad to see it making it somewhere in the manual.

Thanks for joining again. You have mentioned some notable aspects. I'll respond to your other very interesting mail about long-term strategies later.
 
Languages have reserved keywords, so mapping a language to another is likely to clash on some reserved keywords. The amount of clash depends on the languages that we consider and tricks we can apply. One consideration is about the target languages: should we have the same considerations for jOOQ used in Java and jOOQ used in say Scala? I will use "Scala" as a generic way of saying "other languages" throughout the discussion. Of course I understand that jOOQ's primary target is Java, but I am curious.
 
Yes, we should, even if they're only secondary influences. But jOOQ should be as Scala and Groovy interoperable as possible.
 
The only conflict I had with Scala so far was the "val" reserved word, which I solved by duplicating "DSL.val()" into "DSL.value()" for our Scala friends.
 
Note that in the worst case, Scala offers quoting using backticks. I.e. DSL.`val`() is a possible way to access a Java method that would otherwise not be accessible in Scala. This is viable for "remote" keywords, not for frequently used ones, such as AND or SELECT, of course.
 
1. By introducing artificial keywords. Examples

SQL: UPDATE t SET a = 1, b = 2
jOOQ: update(t).set(a, 1).set(b, 2)
Note that this example also shows missing operator overloading capabilities, where "=" is replaced by ","
Would jOOQ on Scala be able to more closely match such construct if one wanted to?
 
Not every operator can be overloaded in Scala. In particular, I think that these cannot be overoaded: = , == !=, but I'm not 100% sure.
Groovy has hird-wired rules for operator "overloading":

I had recently found an interesting PhD thesis on Scala's potential of being a host to internal domain specific languages, like jOOQ:
 
Interestingly, the thesis also internalises SQL, albeit only very superficially.
 
Scala 2.10 also offers Macros, but from what I have seen so far, I am not sure how they can be leveraged. I simply don't understand the current Macro documentation.
 
SQL: ORDER BY
jOOQ: orderBy()
Would jOOQ on Scala be able to more closely match such construct? I guess that would mean having ORDER(BY(xxx)) and then BY could be problematic if used in other places.
 
Scala's ability to omit parentheses in certain cases will lure you into thinking that these things will be useful. This topic is dealt with extensively in the above thesis.
 
Let's look at your example (pseudo Scala, might not be entirely correct):
 
================================
object ScalaDSL {
  def BY(Field f) : ByField = ...
  def BY(SortField f) : BySortField = ...
}
 
trait SelectOrderByStep {
  def ORDER(ByField f) = ...
}
================================

A lot of types like ByField and BySortField would be introduced. These types are only used for DSL syntax implementation. They have no other meaning but can be reused among clauses, e.g. PARTITION BY, GROUP BY.

Another option to implement "ORDER BY field":

================================
trait SelectOrderStep {
  def ORDER : SelectOrderByStep;
}

trait SelectOrderByStep {
  def BY(Field f) : ...
  def BY(SortField f) : ...
}
================================

This becomes a bit different with "three-letter" keyword combinations. Let's take Oracle's ORDER SIBLINGS BY, for instance. The above would then be enhanced to:

================================
trait SelectOrderStep {
  def ORDER : SelectOrderByStep;
  def ORDER(SIBLINGS s) : SelectOrderByStep;
}

object SIBLINGS {}

trait SelectOrderByStep {
  def BY(Field f) : ...
  def BY(SortField f) : ...
}
================================

But the problem here is the fact that introducing a SIBLINGS syntactic element will also introduce ambiguities when writing

================================
ORDER SIBLINGS BY f

// is the above:
ORDER().SIBLINGS().BY(f)

// or is it:
ORDER(SIBLINGS).BY(f)

// apparently, Scala's lexer doesn't know, and the compiler cannot 
// disambiguate this, according to the language reference. Disambiguation:
(ORDER SIBLINGS) BY f
================================

Having exprimented already for a couple of hours (and having read that thesis), I don't think that a truly satisfiable solution where all nasty dots and parentheses can be omitted, is possible in an API that makes heavy use of overloading, such as jOOQ's. The rules are too complex to handle in productive code, and if you don't handle them, you will resort to code that is worse to read, write and maintain than jOOQ's, i.e. ORDER(BY(f)) or ORDER().BY(f) or (ORDER SIBLINGS) BY f.

The worst thing about these techniques is the fact that, *IF* you get something wrong, syntactically, enjoy finding your mistake if you're running a SQL statement like this one:

Feel free to experiment with Scala yourself, though. I'm sure I haven't seen it all, yet :-)
 
6. By using descriptive methods, or a comma

Most SQL operators have to be mapped to descriptive method names in Java:

SQL: =
jOOQ: equal(), eq()

What is the rule with verbs? Should it be 3rd person, like "equals()" (if there were no collisions with Java's equals)?

eq() elegantly solves this problem :-)

As you've correctly guessed, collision with Java's equals() was the problem here. If verbs *had* to be chosen, I would probably have to change greaterThan() into isGreaterThan(), choosing IS to be consistent with IS NULL, IS DISTINCT FROM, etc. Thus, isEqual() would be the "SQL way" to write out "="

That might be a change worth considering for jOOQ 4.0, in a greater context.
 
SQL: <>
jOOQ: notEqual(), ne()

Would jOOQ on Scala be able to more closely match such construct?

7. That cannot be worked around

This is what has been keeping me from implementing CTE so far.

SQL: WITH a(x, y) AS (SELECT 1, 2) SELECT a.x, a.y FROM a

What is the problem with the above expression?

The problem is that a is not well-defined in SELECT a.x, a.y or in FROM a. The above would have to be written as:

Table<?> a = select(val(1), val(2)).asTable("a", "x", "y");

with(a)
.select(a.field("x"), a.field("y"))
.from(a);

It would work, of course. But it wouldn't feel exactly like SQL. And you would lose all typesafety.
 
Discussion

a) by using synonyms

This is the worst suggestion in my view.

Yes, I agree with you. :-) 

As an excuse... at the time I implemented this, I wasn't aware of the fact that jOOQ might eventually go that far. I think, decode() was in there since version 1.0. At least, it's contained in the first Maven-published version:

So, let's consider decode() an early "API blunder"

b) by appending "disambiguators" such as case_ or case$ or case

I don't mind hard rules, like "any keyword that may clash with Java keyword is going to be suffixed with '_'". I prefer suffix, because code completion would work when I start typing "case".

Agreed on the suffix. But I'd really like to avoid this as long as possible. It's quite an "ugly" solution for something as frequent as a CASE expression.
 
c) by introducing artificial spelling, such as casë, casǝ, casɇ ;-)
OK, this *IS* the worst suggestion :)
You forgot \uFF43\uFF41\uFF53\uFF45: case

Great! I was looking for those letters, just didn't find them. Hey, you only need the e, as in case. That way, IDE auto-completion can still help the poor developers, in case they don't remember FF45 ;-)

d) by changing the API to be all-uppercase: SELECT(), CASE(), ORDER_BY()

My initial reaction was "ouch, this is ugly Java", but I do write SQL all caps, so having the DSL part be all caps to map SQL is really not that bad.

Yes, and it would stress the fact that jOOQ is really actually SQL embedded in Java, more typesafely and with more features than SQLJ.

e) by changing the API to be camel-case with an upper-case initial letter: Select(), Case(), OrderBy()

This is odd, because it is neither the Java convention nor SQL.

I have seen it once or twice in a SQL Server / .NET context, although T-SQL uses UPPERCASE in their conventions:

But in .NET, method names are often PascalCased:

It wouldn't be the worst solution, but still odd.
 
d) and e) are massive changes.

Apart from being an incompatible API, what is the complexity? User manual mainly?

Massive in the amount of work for me :-) (and for users if it wasn't backwards-compatible)
You're right, there isn't much complexity. It would simply mean:

- Creating a code-generator that generates delegate methods for one syntax, delegating to the other
- Creating a section in the manual explaining that both are possible
- Creating some indicative integration tests

If it can be guaranteed, that for every orderBy(), there shall also be an ORDER_BY(), the above would be sufficient. And using our new annotations (those for the BNF), it will be easy to discover, which methods need to be duplicated.

If people wanted to reduce their jOOQ binary footprint, they could rebuild jOOQ, omitting the duplication.

Of course, such a strategy would also indicate, that your suggestion is the only viable way to implement case_(), else_(), for_() in the camelCase API.

Any other ideas?

Apart from silly ideas like "cASE", not really :)

caze? elze?
ca$e? el$e?
esac? esle?

Durchholz, Joachim

unread,
Jun 24, 2013, 5:04:44 AM6/24/13
to jooq...@googlegroups.com, Christopher Deckers
> As you can see, there are a lot of caveats when
> implementing an internal domain specific language
> (as opposed to an external one). [...]
> I currently see four ways to solve 5)
>
> a) by using synonyms

Not good, because the synonyms have to be looked up in the API doc.

> b) by appending "disambiguators" such as case_ or case$ or case

Workable but ugly.

> c) by introducing artificial spelling, such as casë, casǝ, casɇ ;-)

Cute :-)
But doesn't solve the problem, since you still have to look up the spelling variation employed in each specific case.

> d) by changing the API to be all-uppercase: SELECT(), CASE(), ORDER_BY()

Workable but awkward to type.
Also awkward to read. Lowercase letters are easier to distinguish than uppercase letters (because the outlines have more variation I think).
And an incompatible change, too.

> e) by changing the API to be camel-case with an upper-case initial letter: Select(), Case(), OrderBy()

Workable but an incompatible change.

> Any other ideas?

None. You've been quite thorough here.

I see a slightly different issue at work here: Most replacements are more-or-less obvious choices, but decode() is a nonobvious replacement for IF/CASE.
It's essentially perpetuating the misnaming of Oracle's DECODE(). It sort-of makes sense to do it that way, but it won't be understood or appreciated by those who work in other languages. Given the tool wars many people entertain, reusing Oracle nomenclature might even mark you as adherent of one particular camp.
select() might work. choice() could even be an even better, erm, choice. Or maybe choose().

Lukas Eder

unread,
Jun 24, 2013, 11:52:47 AM6/24/13
to jooq...@googlegroups.com, Christopher Deckers, Joachim


2013/6/24 Durchholz, Joachim <Joachim....@hennig-fahrzeugteile.de>

> As you can see, there are a lot of caveats when
> implementing an internal domain specific language
> (as opposed to an external one). [...]
> I currently see four ways to solve 5)
>
> a) by using synonyms

Not good, because the synonyms have to be looked up in the API doc.

> b) by appending "disambiguators" such as case_ or case$ or case

Workable but ugly.

> c) by introducing artificial spelling, such as casë, casǝ, casɇ ;-)

Cute :-)
But doesn't solve the problem, since you still have to look up the spelling variation employed in each specific case.
 
Not when leveraging auto-completion. But that wasn't such a serious proposition anyway ;-9
 
> d) by changing the API to be all-uppercase: SELECT(), CASE(), ORDER_BY()

Workable but awkward to type.
Also awkward to read. Lowercase letters are easier to distinguish than uppercase letters (because the outlines have more variation I think).
And an incompatible change, too.
 
If this is introduced, camelCasing and UPPER_CASING would be maintained in parallel (see the other mails). This leaves the choice of casing up to the user.
 
I agree about the typing, if not using syntax auto-completion in an IDE. On the other hand, jOOQ is a very IDE-friendly API...
 
> e) by changing the API to be camel-case with an upper-case initial letter: Select(), Case(), OrderBy()

Workable but an incompatible change.
 
Again, there would be no incompatibility, as these API variants can be maintained in parallel.
 
> Any other ideas?

None. You've been quite thorough here.

I see a slightly different issue at work here: Most replacements are more-or-less obvious choices, but decode() is a nonobvious replacement for IF/CASE.
It's essentially perpetuating the misnaming of Oracle's DECODE(). It sort-of makes sense to do it that way, but it won't be understood or appreciated by those who work in other languages. Given the tool wars many people entertain, reusing Oracle nomenclature might even mark you as adherent of one particular camp.
 
I am. Thus, Oracle is supported particularly well by jOOQ. But you are right. In this case, DECODE() wasn't the best choice.
 
select() might work. choice() could even be an even better, erm, choice. Or maybe choose().
 
Yes, "choose" would be much better. Given that "else" is mapped to "otherwise", "choose" wouldn't be too bad. This would at least remind of XSL or JSTL. Both XSL and JSTL also know "then", so it would at least be more consistent.
 
I guess, a short-term solution would include either "case_" or "choose"

Roger Thomas

unread,
Jun 24, 2013, 3:42:53 PM6/24/13
to jooq...@googlegroups.com, Christopher Deckers, Joachim
Yes, "choose" would be much better. Given that "else" is mapped to "otherwise", "choose" wouldn't be too bad. This would at least remind of XSL or JSTL. Both XSL and JSTL also know "then", so it would at least be more consistent.
 
I guess, a short-term solution would include either "case_" or "choose"

If you are looking to add a nice short-term solution if would say case_ (and I guess else_) as both of these use the correct SQL verb and would both operate correctly in an IDE lookahead editor.

Roger

Lukas Eder

unread,
Jun 25, 2013, 2:31:36 AM6/25/13
to jooq...@googlegroups.com, Christopher Deckers, Joachim


2013/6/24 Roger Thomas <rithom...@gmail.com>

Yes, "choose" would be much better. Given that "else" is mapped to "otherwise", "choose" wouldn't be too bad. This would at least remind of XSL or JSTL. Both XSL and JSTL also know "then", so it would at least be more consistent.
 
I guess, a short-term solution would include either "case_" or "choose"

If you are looking to add a nice short-term solution if would say case_ (and I guess else_) as both of these use the correct SQL verb and would both operate correctly in an IDE lookahead editor.
 
I'm also inclined towards these, even if they're a bit ugly. But *if* the ALL_UPPER_CASE() API is added, then suffixing is the only option for the camelCase() API for API consistency and predictability between the two. And adding them now would prevent deprecating decode() *and* choose() in a later release.
Reply all
Reply to author
Forward
0 new messages