Crystal: Titlecase vs Camelcase

Created on 24 Apr 2019  路  22Comments  路  Source: crystal-lang/crystal

This api String#camelcase seems to be what I have heard called titlecase. Should there be two apis camelcase and titlecase?

"hello_world".camelcase #=> "helloWorld"
"hello_world".titlecase #=> "HelloWorld"

Most helpful comment

It's much more confusing than that. Citing the wikipedia article:

  • Title Case (...) capitalises all words but retains the spaces between them;
  • upper camel case (initial uppercase letter, also known as Pascal case);
  • lower camel case (initial lowercase letter, also known as Dromedary case[4]) ;
  • other synonyms include:

Title case is used in English literature and newspapers to capitalize titles, for example "very blunt title" will become "Very Blunt Title". There is no String#titlecase in Crystal.

In Crystal String#camelcase means what wikipedia calls "upper camel case", and is the counterpart to String#underscore, where "very_blunt_title" is inflected to "VeryBluntTitle". This follows Ruby on Rails string inflectors, and is common to translate from a method name (foo_bar) to a class name (FooBar).

IMO: using some other namings than #underscore and #camelcase would introduce some unwanted confusion/friction between the Ruby/Rails and Crystal worlds.

All 22 comments

camelcase does indeed have two conflicting definitions...
or perhaps the only required property is that it has uppercase letters in the middle (regardless of the first letter).

This is why I say that your suggested change provides no improvement over the current status.
And, since it's backwards-incompatible (in potentially dangerous ways), I'd just like to shoot this down entirely...

I'd support mixedcase + titlecase though (get rid of the ambiguous camelcase)

Wiki says that camelCase has single definition.

There's camelCase and PascalCase

@vladfaust wiki says:

Some programming styles prefer camel case with the first letter capitalised, others not.[1][2][3] For clarity, this article calls the two alternatives upper camel case (initial uppercase letter, also known as Pascal case) and lower camel case (initial lowercase letter, also known as Dromedary case[4]). Some people and organizations, notably Microsoft,[2] use the term camel case only for lower camel case.

I like the PascalCase idea though (because i like pascal).

It's much more confusing than that. Citing the wikipedia article:

  • Title Case (...) capitalises all words but retains the spaces between them;
  • upper camel case (initial uppercase letter, also known as Pascal case);
  • lower camel case (initial lowercase letter, also known as Dromedary case[4]) ;
  • other synonyms include:

Title case is used in English literature and newspapers to capitalize titles, for example "very blunt title" will become "Very Blunt Title". There is no String#titlecase in Crystal.

In Crystal String#camelcase means what wikipedia calls "upper camel case", and is the counterpart to String#underscore, where "very_blunt_title" is inflected to "VeryBluntTitle". This follows Ruby on Rails string inflectors, and is common to translate from a method name (foo_bar) to a class name (FooBar).

IMO: using some other namings than #underscore and #camelcase would introduce some unwanted confusion/friction between the Ruby/Rails and Crystal worlds.

FYI I often need lower camelcase in my apps, leading to string.camelcase.sub(&.downcase), which is slightly confusing.

Would it make sense to add these options as an option to #camecase?

Ruby on Rails defines String#camelcase(first_letter = :upper) which defaults to upper camel case but you specify str.camelcase(:lower) for lower camel case, and thus can support both formats. We can achieve the same with an enum:

```crystal
class String
enum CamelCase
Upper
Lower
end

def camelcase(first_letter : CamelCase = :upper)
# ...
end
end

@ysbaddaden wouldn't having a bool argument be enough?

What about making the API more extensible then just special casing the first letter.
I propose using an enum CaseStyle and having a parameter named style.

class String
  enum CaseStyle
    Title
    Upper
    Lower
    #=> add more as desired
  end

  def camelcase(style : CamelCase = :upper)
    # ...
  end
end

@wontruefree in that case it shouldn't be named "camelcase" anymore, because titlecase isn't camelcase.
Maybe with_case?

@konovod I thought from the wiki article linked above "titlecase" is a kind of "camelcase". If that is correct then the name #camecase makes sense.

@wontruefree No,

Camel case is distinct from Title Case, which capitalises all words but retains the spaces between them

@konovod that makes sense I was looking at the wiki page that had some listed under "Variations and synonyms"

What about having a generic #format method?

I don't think this needs any action apart from maybe adding a first_letter argument to String#camelcase as proposed in https://github.com/crystal-lang/crystal/issues/7709#issuecomment-486290854

@sija it can be a bool; it would avoid an enum (or plain symbols). Maybe String#camelcase(lower = false)?

@ysbaddaden I'd go for sth moar descriptive, like String#camelcase(lowercase_first_letter = false)

That leads to tedious calls:

  • str.camelcase(lowercase_first_letter: true)

Versus:

  • str.camelcase(lower: true)

That's probably why Rails went with first_letter: :lower since it's short and expressive. lower alone IMO would be misleading.

Maybe using enum wouldn't be such a bad idea after all...

I don't know about using an Enum if there are only 2 values.
But it is more succinct than the boolean.

Ruby has explicit kwargs, the Rails method is just str.camelcase(:lower) which is explicit since "lower camel case" means that the first letter is lowercase.

Anyway, we're bikeshedding. This is just one method. An enum is overkill, and #camelcase(lower = false) is enough.

Yes we're bikeshedding but we should make it a keyword argument if using a boolean, "foo".camelcase(true) vs "foo".camelcase(false) is just confusing, which is which?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

asterite picture asterite  路  3Comments

grosser picture grosser  路  3Comments

ArthurZ picture ArthurZ  路  3Comments

asterite picture asterite  路  3Comments

lbguilherme picture lbguilherme  路  3Comments