# Why is either Listable or HoldFirst not working?

Starting with a fresh kernel, I evaluate the following:

Questions = {
{"What is the capital of Switzerland?", "Bern", {"Vaduz", "Berlin", "Vienna"}},
{"Who is the king of the jungle?", "Lion", {"Giraffe", "Mouse", "Monkey"}},
{"2+2?" , "4", {"15", "13", "1e15"}}
} ;
Dynamic@Column@Questions

SetAttributes[DynamicInputField, {HoldFirst, Listable}];
DynamicInputField[var_, OptionsPattern[ContentType -> Expression]] :=
InputField[Dynamic[var], OptionValue[ContentType],
ContinuousAction -> True, ImageSize -> Full];

Dynamic@Grid[{
{"Statement", DynamicInputField[Questions[[1, 1]], ContentType -> String]},
{"Answer", DynamicInputField[Questions[[1, 2]], ContentType -> String]},
Column[DynamicInputField[#, ContentType -> String] & /@ Questions[[1, 3]],
BaselinePosition -> Top]
}
}, Alignment -> Left]


I must say that I took me a while to find out that I needed to set HoldFirst as an attribute for my function to work at least with the first two input fields. Nevertheless, the function does not work by mapping it into a list, i.e., the three last input fields send a error, the same one I had before I set HoldFirst as an attribute:

Set::setraw : Cannot assign to raw object Vaduz.>>


What am I doing wrong? I also tried the following:

Column[DynamicInputField[Questions[[1, 3]], ContentType -> String],
BaselinePosition -> Top]


Column[Table[
DynamicInputField[Questions[[1, 3, n]], ContentType -> String],
{n, 3}], BaselinePosition -> Top]


Giving the errors:

Part::pkspec1 : The expression n cannot be used as a part specification.>>


even when I put the Table inside a With[[n=n],...].

Moreover, why is not the same result in my two attempts of "solving" even though the function was set to be listable?

### Fundamental problem

Pardon me if I miss some points of your question as I didn't attempt to understand what your code is intended to do, because I think I understand what the problem is from the title alone. Please consider:

SetAttributes[f, {HoldFirst, Listable}];

f[x_] := foo[x]

f[{1, 2, 3}]

{foo[1], foo[2], foo[3]}

bar = {1, 2, 3};
f[bar]

foo[{1, 2, 3}]


Listable can only work across lists that it can "see" and HoldFirst prevents bar from evaluating to an explicit list.

### Analysis of attempts

Your first attempt: Column[DynamicInputField[ . . . fails because the expression returned by DynamicInputField is not a List but an InputField, therefore Column has nothing to format.

Your second attempt is almost correct except that n is not evaluated (because of HoldFirst).
It will work if you put the With inside the Table:

Column[Table[
With[{n = n}, DynamicInputField[Questions[[1, 3, n]], ContentType -> String]], {n, 3}],
BaselinePosition -> Top]


It would be simpler however to use Array. (See below.)

### Proposed solution

I believe this will work as you require.

ClearAll[DynamicInputField]
SetAttributes[DynamicInputField, {HoldFirst, Listable}];

DynamicInputField[var_, opts___] /; ListQ[var] :=
Column @ Array[DynamicInputField[var[[#]], opts] &, Length @ var]

DynamicInputField[var_, OptionsPattern[ContentType -> Expression]] :=
InputField[Dynamic[var], OptionValue[ContentType], ContinuousAction -> True,
ImageSize -> Full];


Test:

DynamicInputField[Questions[[1, 3]], ContentType -> String]


Also:

DynamicInputField[Questions[[1]], ContentType -> String]


• Specifically, I would like that DynamicInputFiled worked by giving it either a variable like Question[[1,1]] or by giving it a list such as Question[[1,3]] by giving me a FieldInput as defined or a list of those. I didn't know what you mentioned above about how Listable "sees". That might be the reason it doesn't work. – Carlos Chida Jul 29 '14 at 12:00
• @Carlos Okay, I actually read your code this time. I believe that this is indeed the problem, but I don't see a simple solution because of the way this is written. Let me think about this. – Mr.Wizard Jul 29 '14 at 12:08
• Thanks. And by giving it a second though, I don't actually need that the function can handle either an expression or a list - by being able to map it to a list should do (I tried that but didn't work either). – Carlos Chida Jul 29 '14 at 12:17
• As suggested by @Mr.Wizard, removing HoldFirst and then just using Column[DynamicInputField[Questions[[1, 3]], ContentType -> String], BaselinePosition -> Top] works for me. – carlosayam Jul 29 '14 at 12:25
• @Carlos Please see my extended answer. – Mr.Wizard Jul 29 '14 at 12:25