# CharacterRange oddity [closed]

CharacterRange documentation says that it returns a list. However, if I define

letters[n_] := CharacterRange["\[Alpha]", "\[CurlyPhi]"][[;; n]]


and then ask for Part[letters, 3], I get Part::partd. If I ask for Last[letters] I get Last::normal. What gives?

• try n=4; Part[letters[n], 3]
– kglr
Oct 7 '17 at 15:48
• OK, this one is on me for using code I don't completely grok. That last bit with the n in the definition of letters, what is it doing? Are you redefining it with your statement? Oct 7 '17 at 15:51
• jamesson, see tutorial/DefiningFunctions
– kglr
Oct 7 '17 at 15:58
• If you really don't understand what functions are (in the programming sense), then it's time to go through a basic tutorial: wolfram.com/language/elementary-introduction/2nd-ed There is a minimum level of expected Mathematica knowledge before asking on this website. Oct 7 '17 at 18:36
• No, trust me, I know what a function is :). I have spent the past 2 hours reading about Mathematica scope, it is... interesting. Oct 7 '17 at 18:39

While e.g., letters[5] (or any other integer between 1 and 22) is a list, letters is not. Colloquially, letters is a function, which is implementing in Mathematica as a symbol with DownValues.

You can think of DownValues as rules which are applied during the sequence of evaluation, so that letters[5] evaluates to {"α", "β", "γ", "δ", "ε"}.

In fact, you can query the DownValues of letters with fairly readable results:

DownValues[ letters ]

{ HoldPattern[letters[n_]] :> CharacterRange["α", "φ"][[1 ;; n]] }


(HoldPattern is just a way of making sure the left hand side of the rule doesn't evaluate before the rule can be applied.)

1. No subpart of letters[[3]] is of the form letters[n_], so the DownValue couldn't apply
2. More noticeably, Part immediately tries to evaluate, even if its first argument has insufficient length/depth, which results in your error.

If you'd like to use the syntax letters[[3]] to return "α", you can instead redefine letters:

ClearAll[ letters ]  (* Remove DownValues *)
letters = CharacterRange["α", "φ"];

letters

{"α", "β", "γ", "δ", "ε", "ζ", "η", "θ", "ι", "κ", "λ", "μ", "ν", "ξ", "ο", "π", "ρ", "ς", "σ", "τ", "υ", "φ"}

letters[[3]]

"γ"


Fun fact: while SetDelayed (:=) statements are stored as rules in DownValues, Set (=) statements are stored in OwnValues :

 OwnValues[ letters ]  (* after using = rather than := *)

{ HoldPattern[letters] :> {"α", "β", "γ", "δ", "ε", "ζ", "η", "θ", "ι", "κ", "λ", "μ", "ν", "ξ", "ο", "π", "ρ", "ς", "σ", "τ", "υ", "φ"} }

• Very cool, I must study this Oct 7 '17 at 18:37