One interesting issue, here, is that the concise expression in J is not because J was specifically optimized for this task, but because J has so many expressions which can be used for this task.
But some people had expressed confusion, about how to read one of my drafts: f=:[:|:((i.|.-.)~(a.{~65 97+/i.26)&(*@#.@e.,@#[))"0 So I thought I'd spend a few moments going over its grammar. This may feel tedious if you have already figured out how that sentence works. First, the top level grammar is: f=:verb and you can test this, after you define f: nc<'f' 3 Here's the complete list of classes that a name can have: 3 verb 2 conjunction 1 adverb 0 noun _1 undefined _2 invalid name And any [valid] parenthesized expression can be assigned to any [valid] name and you can use nc to test what kind of value the name refers to. Here's how that verb breaks out, at the top level: [: |: ((i.|.-.)~(a.{~65 97+/i.26)&(*@#.@e.,@#[))"0 That's three verbs -- a fork. (Basically all that's happening here, is that I'm transposing the result, which is how I get the horizontal vs. vertical arrangement in this implementation -- a single letter argument will give me a 1 dimensional array which is unchanged by transpose.) Also, the rightmost verb has this grammar: (verb) conjunction noun It's the inner verb here which is complex (and which you sort of have to understand before the rest makes sense). That inner verb looks like this: (i.|.-.)~ (a.{~65 97+/i.26)&(*@#.@e.,@#[) In other words, it's two verbs -- a hook. And remember: we always use the dyadic definition of the left verb in a hook and the monadic definition of the right verb in a hook. (For forks, we always use the dyadic definition for the "middle" verb of the fork but the grammatical context of other verbs depends on the grammatical context where the fork is used). Anyways, the rightmost verb in this hook works like this: (a.{~65 97+/i.26)&(*@#.@e.,@#[) 'c' abcdefghijklmnopqrstuvwxyz It's a lower case alphabet if the argument is lower case, an upper case alphabet if the argument is upper case, and blank otherwise. The left verb works like this: 'c' (i.|.-.)~ 'abcdefghijklmnopqrstuvwxyz' defghijklmnopqrstuvwxyzab or we can get rid of that cross adverb, swapping the arguments: 'abcdefghijklmnopqrstuvwxyz' (i.|.-.) 'c' defghijklmnopqrstuvwxyzab And, of course, we can break it down further: 'abcdefghijklmnopqrstuvwxyz' i. 'c' 2 'abcdefghijklmnopqrstuvwxyz' -. 'c' abdefghijklmnopqrstuvwxyz In other words, it's removing the 'c' from the alphabet and rotating the leftmost two characters onto the righthand side. (You can try out the |. for yourself...) That only leaves this verb: (a.{~65 97+/i.26)&(*@#.@e.,@#[) which (if you nave linear display representation turned on) J shows as: (2 26$'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')&(*@#.@e. ,@# [) So it's a noun (the two alphabets) which is the left argument to the verb (*@#.@e. ,@# [) And remember that this whole thing is inside that (verb)"0 construct, so we will only ever see a single letter here. The left tine of the fork is *@#.@e. and this tells us which alphabet our argument character is in. (a.{~65 97+/i.26) *@#.@e. 'a' 0 1 (a.{~65 97+/i.26) *@#.@e. 'A' 1 0 (a.{~65 97+/i.26) *@#.@e. '-' 0 0 If we strip that down to just the e. it looks more like this: (a.{~65 97+/i.26) e. 'a' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 But #. will interpret each row as a binary representation of an integer: #.(a.{~65 97+/i.26) e. 'a' 0 33554432 And, * will tell us the sign of that integer (it's 1 or 0) *#.(a.{~65 97+/i.26) e. 'a' 0 1 Hopefully, the rest is obvious... -- Raul ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm