Popular Threads From Developers:
List Statistics
- Total Threads: 675
- Total Posts: 2049
Phrases Used to Find This Thread
|
# 1

29-03-2011 02:52 PM
|
|
|
Anyone else have opinions on which of these two basic approaches they
prefer? Tom, any thoughts?
David
On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
> But consider again the macro definitions which would allow
>
> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>
> or
>
> DefineIntTable(data, 123, 456, 789);
>
> These pass the usefulness test with flying colors, are really easy to
> explain, and don't have any off-putting squiggles. They solve all the
> global/local technical difficulties I describe below, yet look comfortably
> familiar to the beginner's eye. The objection, I believe, is that they look
> like function calls, and function calls seem wrong floating in space at
> global scope. But those who raise this objection do so precisely because
> they are intimate with the language. I suspect beginners would hardly be
> fazed. And whatever minor confusions the syntax might present are surely
> easier to document away than, say,
>
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>
> My point is that I think the ability to define Flash-based table objects at
> any scope with a tight and reasonable syntax warrants reconsideration of the
> Definexxx() style macros, despite the similarity to function calls. Some
> concepts are compelling enough to suggest tiny stretches of the language
> boundaries. F() is one of those, and I think tables are too.
>
> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
|
# 2

29-03-2011 04:26 PM
|
|
|
Anyone else have opinions on which of these two basic approaches they
prefer? Tom, any thoughts?
David
On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
> But consider again the macro definitions which would allow
>
> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>
> or
>
> DefineIntTable(data, 123, 456, 789);
>
> These pass the usefulness test with flying colors, are really easy to
> explain, and don't have any off-putting squiggles. They solve all the
> global/local technical difficulties I describe below, yet look comfortably
> familiar to the beginner's eye. The objection, I believe, is that they look
> like function calls, and function calls seem wrong floating in space at
> global scope. But those who raise this objection do so precisely because
> they are intimate with the language. I suspect beginners would hardly be
> fazed. And whatever minor confusions the syntax might present are surely
> easier to document away than, say,
>
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>
> My point is that I think the ability to define Flash-based table objects at
> any scope with a tight and reasonable syntax warrants reconsideration of the
> Definexxx() style macros, despite the similarity to function calls. Some
> concepts are compelling enough to suggest tiny stretches of the language
> boundaries. F() is one of those, and I think tables are too.
>
> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I'm a little confused. can you explain the two approaches succinctly?
t.
On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> Anyone else have opinions on which of these two basic approaches they
> prefer? Tom, any thoughts?
>
> David
>
> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>> But consider again the macro definitions which would allow
>>
>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>
>> or
>>
>> DefineIntTable(data, 123, 456, 789);
>>
>> These pass the usefulness test with flying colors, are really easy to
>> explain, and don't have any off-putting squiggles. They solve all the
>> global/local technical difficulties I describe below, yet look comfortably
>> familiar to the beginner's eye. The objection, I believe, is that they look
>> like function calls, and function calls seem wrong floating in space at
>> global scope. But those who raise this objection do so precisely because
>> they are intimate with the language. I suspect beginners would hardly be
>> fazed. And whatever minor confusions the syntax might present are surely
>> easier to document away than, say,
>>
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> My point is that I think the ability to define Flash-based table objects at
>> any scope with a tight and reasonable syntax warrants reconsideration of the
>> Definexxx() style macros, despite the similarity to function calls. Some
>> concepts are compelling enough to suggest tiny stretches of the language
>> boundaries. F() is one of those, and I think tables are too.
>>
>> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
|
# 3

29-03-2011 08:22 PM
|
|
|
Anyone else have opinions on which of these two basic approaches they
prefer? Tom, any thoughts?
David
On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
> But consider again the macro definitions which would allow
>
> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>
> or
>
> DefineIntTable(data, 123, 456, 789);
>
> These pass the usefulness test with flying colors, are really easy to
> explain, and don't have any off-putting squiggles. They solve all the
> global/local technical difficulties I describe below, yet look comfortably
> familiar to the beginner's eye. The objection, I believe, is that they look
> like function calls, and function calls seem wrong floating in space at
> global scope. But those who raise this objection do so precisely because
> they are intimate with the language. I suspect beginners would hardly be
> fazed. And whatever minor confusions the syntax might present are surely
> easier to document away than, say,
>
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>
> My point is that I think the ability to define Flash-based table objects at
> any scope with a tight and reasonable syntax warrants reconsideration of the
> Definexxx() style macros, despite the similarity to function calls. Some
> concepts are compelling enough to suggest tiny stretches of the language
> boundaries. F() is one of those, and I think tables are too.
>
> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I'm a little confused. can you explain the two approaches succinctly?
t.
On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> Anyone else have opinions on which of these two basic approaches they
> prefer? Tom, any thoughts?
>
> David
>
> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>> But consider again the macro definitions which would allow
>>
>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>
>> or
>>
>> DefineIntTable(data, 123, 456, 789);
>>
>> These pass the usefulness test with flying colors, are really easy to
>> explain, and don't have any off-putting squiggles. They solve all the
>> global/local technical difficulties I describe below, yet look comfortably
>> familiar to the beginner's eye. The objection, I believe, is that they look
>> like function calls, and function calls seem wrong floating in space at
>> global scope. But those who raise this objection do so precisely because
>> they are intimate with the language. I suspect beginners would hardly be
>> fazed. And whatever minor confusions the syntax might present are surely
>> easier to document away than, say,
>>
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> My point is that I think the ability to define Flash-based table objects at
>> any scope with a tight and reasonable syntax warrants reconsideration of the
>> Definexxx() style macros, despite the similarity to function calls. Some
>> concepts are compelling enough to suggest tiny stretches of the language
>> boundaries. F() is one of those, and I think tables are too.
>>
>> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
They both do the same thing: create an object that allows you to
access data stored in program memory (flash) using the [] array access
syntax. The question is which syntax we prefer for doing so:
DefineIntTable(data, 123, 456, 789);
Or (and here we could replace "PROGMEM" with any other word):
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Or (and again, we can use any names here):
IntData data[] = { 123, 456, 789 };
IntTable sample(data);
Any preferences?
It's apparently impossible to do any of these:
IntTable sample = { 123, 456, 789 };
IntTable sample(123, 456, 789);
IntTable sample = IntTable(123, 456, 789);
IntTable sample = IntTableData(123, 456, 789);
at least, not in way that works at global scope (outside of a
function), which seems like the most important place to be able to
define a lookup table.
David
On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
> I'm a little confused. can you explain the two approaches succinctly?
>
> t.
>
> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>
>> Anyone else have opinions on which of these two basic approaches they
>> prefer? Tom, any thoughts?
>>
>> David
>>
>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>> But consider again the macro definitions which would allow
>>>
>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>
>>> or
>>>
>>> DefineIntTable(data, 123, 456, 789);
>>>
>>> These pass the usefulness test with flying colors, are really easy to
>>> explain, and don't have any off-putting squiggles. They solve all the
>>> global/local technical difficulties I describe below, yet look comfortably
>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>> like function calls, and function calls seem wrong floating in space at
>>> global scope. But those who raise this objection do so precisely because
>>> they are intimate with the language. I suspect beginners would hardly be
>>> fazed. And whatever minor confusions the syntax might present are surely
>>> easier to document away than, say,
>>>
>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>> IntTable sample(data);
>>>
>>> My point is that I think the ability to define Flash-based table objects at
>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>> Definexxx() style macros, despite the similarity to function calls. Some
>>> concepts are compelling enough to suggest tiny stretches of the language
>>> boundaries. F() is one of those, and I think tables are too.
>>>
>>> Mikal
>
>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
|
# 4

29-03-2011 08:25 PM
|
|
|
Anyone else have opinions on which of these two basic approaches they
prefer? Tom, any thoughts?
David
On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
> But consider again the macro definitions which would allow
>
> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>
> or
>
> DefineIntTable(data, 123, 456, 789);
>
> These pass the usefulness test with flying colors, are really easy to
> explain, and don't have any off-putting squiggles. They solve all the
> global/local technical difficulties I describe below, yet look comfortably
> familiar to the beginner's eye. The objection, I believe, is that they look
> like function calls, and function calls seem wrong floating in space at
> global scope. But those who raise this objection do so precisely because
> they are intimate with the language. I suspect beginners would hardly be
> fazed. And whatever minor confusions the syntax might present are surely
> easier to document away than, say,
>
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>
> My point is that I think the ability to define Flash-based table objects at
> any scope with a tight and reasonable syntax warrants reconsideration of the
> Definexxx() style macros, despite the similarity to function calls. Some
> concepts are compelling enough to suggest tiny stretches of the language
> boundaries. F() is one of those, and I think tables are too.
>
> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I'm a little confused. can you explain the two approaches succinctly?
t.
On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> Anyone else have opinions on which of these two basic approaches they
> prefer? Tom, any thoughts?
>
> David
>
> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>> But consider again the macro definitions which would allow
>>
>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>
>> or
>>
>> DefineIntTable(data, 123, 456, 789);
>>
>> These pass the usefulness test with flying colors, are really easy to
>> explain, and don't have any off-putting squiggles. They solve all the
>> global/local technical difficulties I describe below, yet look comfortably
>> familiar to the beginner's eye. The objection, I believe, is that they look
>> like function calls, and function calls seem wrong floating in space at
>> global scope. But those who raise this objection do so precisely because
>> they are intimate with the language. I suspect beginners would hardly be
>> fazed. And whatever minor confusions the syntax might present are surely
>> easier to document away than, say,
>>
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> My point is that I think the ability to define Flash-based table objects at
>> any scope with a tight and reasonable syntax warrants reconsideration of the
>> Definexxx() style macros, despite the similarity to function calls. Some
>> concepts are compelling enough to suggest tiny stretches of the language
>> boundaries. F() is one of those, and I think tables are too.
>>
>> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
They both do the same thing: create an object that allows you to
access data stored in program memory (flash) using the [] array access
syntax. The question is which syntax we prefer for doing so:
DefineIntTable(data, 123, 456, 789);
Or (and here we could replace "PROGMEM" with any other word):
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Or (and again, we can use any names here):
IntData data[] = { 123, 456, 789 };
IntTable sample(data);
Any preferences?
It's apparently impossible to do any of these:
IntTable sample = { 123, 456, 789 };
IntTable sample(123, 456, 789);
IntTable sample = IntTable(123, 456, 789);
IntTable sample = IntTableData(123, 456, 789);
at least, not in way that works at global scope (outside of a
function), which seems like the most important place to be able to
define a lookup table.
David
On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
> I'm a little confused. can you explain the two approaches succinctly?
>
> t.
>
> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>
>> Anyone else have opinions on which of these two basic approaches they
>> prefer? Tom, any thoughts?
>>
>> David
>>
>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>> But consider again the macro definitions which would allow
>>>
>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>
>>> or
>>>
>>> DefineIntTable(data, 123, 456, 789);
>>>
>>> These pass the usefulness test with flying colors, are really easy to
>>> explain, and don't have any off-putting squiggles. They solve all the
>>> global/local technical difficulties I describe below, yet look comfortably
>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>> like function calls, and function calls seem wrong floating in space at
>>> global scope. But those who raise this objection do so precisely because
>>> they are intimate with the language. I suspect beginners would hardly be
>>> fazed. And whatever minor confusions the syntax might present are surely
>>> easier to document away than, say,
>>>
>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>> IntTable sample(data);
>>>
>>> My point is that I think the ability to define Flash-based table objects at
>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>> Definexxx() style macros, despite the similarity to function calls. Some
>>> concepts are compelling enough to suggest tiny stretches of the language
>>> boundaries. F() is one of those, and I think tables are too.
>>>
>>> Mikal
>
>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
These are all baby steps toward std::vector. It might be worth taking some inspiration from that direction, one way or another.
= Mike
On Mar 29, 2011, at 12:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
|
# 5

29-03-2011 08:57 PM
|
|
|
Anyone else have opinions on which of these two basic approaches they
prefer? Tom, any thoughts?
David
On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
> But consider again the macro definitions which would allow
>
> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>
> or
>
> DefineIntTable(data, 123, 456, 789);
>
> These pass the usefulness test with flying colors, are really easy to
> explain, and don't have any off-putting squiggles. They solve all the
> global/local technical difficulties I describe below, yet look comfortably
> familiar to the beginner's eye. The objection, I believe, is that they look
> like function calls, and function calls seem wrong floating in space at
> global scope. But those who raise this objection do so precisely because
> they are intimate with the language. I suspect beginners would hardly be
> fazed. And whatever minor confusions the syntax might present are surely
> easier to document away than, say,
>
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>
> My point is that I think the ability to define Flash-based table objects at
> any scope with a tight and reasonable syntax warrants reconsideration of the
> Definexxx() style macros, despite the similarity to function calls. Some
> concepts are compelling enough to suggest tiny stretches of the language
> boundaries. F() is one of those, and I think tables are too.
>
> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I'm a little confused. can you explain the two approaches succinctly?
t.
On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> Anyone else have opinions on which of these two basic approaches they
> prefer? Tom, any thoughts?
>
> David
>
> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>> But consider again the macro definitions which would allow
>>
>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>
>> or
>>
>> DefineIntTable(data, 123, 456, 789);
>>
>> These pass the usefulness test with flying colors, are really easy to
>> explain, and don't have any off-putting squiggles. They solve all the
>> global/local technical difficulties I describe below, yet look comfortably
>> familiar to the beginner's eye. The objection, I believe, is that they look
>> like function calls, and function calls seem wrong floating in space at
>> global scope. But those who raise this objection do so precisely because
>> they are intimate with the language. I suspect beginners would hardly be
>> fazed. And whatever minor confusions the syntax might present are surely
>> easier to document away than, say,
>>
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> My point is that I think the ability to define Flash-based table objects at
>> any scope with a tight and reasonable syntax warrants reconsideration of the
>> Definexxx() style macros, despite the similarity to function calls. Some
>> concepts are compelling enough to suggest tiny stretches of the language
>> boundaries. F() is one of those, and I think tables are too.
>>
>> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
They both do the same thing: create an object that allows you to
access data stored in program memory (flash) using the [] array access
syntax. The question is which syntax we prefer for doing so:
DefineIntTable(data, 123, 456, 789);
Or (and here we could replace "PROGMEM" with any other word):
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Or (and again, we can use any names here):
IntData data[] = { 123, 456, 789 };
IntTable sample(data);
Any preferences?
It's apparently impossible to do any of these:
IntTable sample = { 123, 456, 789 };
IntTable sample(123, 456, 789);
IntTable sample = IntTable(123, 456, 789);
IntTable sample = IntTableData(123, 456, 789);
at least, not in way that works at global scope (outside of a
function), which seems like the most important place to be able to
define a lookup table.
David
On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
> I'm a little confused. can you explain the two approaches succinctly?
>
> t.
>
> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>
>> Anyone else have opinions on which of these two basic approaches they
>> prefer? Tom, any thoughts?
>>
>> David
>>
>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>> But consider again the macro definitions which would allow
>>>
>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>
>>> or
>>>
>>> DefineIntTable(data, 123, 456, 789);
>>>
>>> These pass the usefulness test with flying colors, are really easy to
>>> explain, and don't have any off-putting squiggles. They solve all the
>>> global/local technical difficulties I describe below, yet look comfortably
>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>> like function calls, and function calls seem wrong floating in space at
>>> global scope. But those who raise this objection do so precisely because
>>> they are intimate with the language. I suspect beginners would hardly be
>>> fazed. And whatever minor confusions the syntax might present are surely
>>> easier to document away than, say,
>>>
>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>> IntTable sample(data);
>>>
>>> My point is that I think the ability to define Flash-based table objects at
>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>> Definexxx() style macros, despite the similarity to function calls. Some
>>> concepts are compelling enough to suggest tiny stretches of the language
>>> boundaries. F() is one of those, and I think tables are too.
>>>
>>> Mikal
>
>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
These are all baby steps toward std::vector. It might be worth taking some inspiration from that direction, one way or another.
= Mike
On Mar 29, 2011, at 12:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I don't like the first version because it's unclear that data is {123, 456, 789}. It seems like data is one more element in the intTable. It should be clear that data is not the same class of thing as the things which comprise it.
The nice thing about the PROGMEM keyword is that it makes it explicit that there is something special about this array. Even if I don't yet know what an intTable is, I know there is a difference between
int data[] PROGMEM = { 123, 456, 789 };
and
int data[] = { 123, 456, 789 };
So on the whole I guess that means I prefer:
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Presumably then when I want to acces the data, I do this:
int foo = sample[1];
Serial.print(foo, DEC);
On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
|
# 6

30-03-2011 12:55 AM
|
|
|
Anyone else have opinions on which of these two basic approaches they
prefer? Tom, any thoughts?
David
On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
> But consider again the macro definitions which would allow
>
> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>
> or
>
> DefineIntTable(data, 123, 456, 789);
>
> These pass the usefulness test with flying colors, are really easy to
> explain, and don't have any off-putting squiggles. They solve all the
> global/local technical difficulties I describe below, yet look comfortably
> familiar to the beginner's eye. The objection, I believe, is that they look
> like function calls, and function calls seem wrong floating in space at
> global scope. But those who raise this objection do so precisely because
> they are intimate with the language. I suspect beginners would hardly be
> fazed. And whatever minor confusions the syntax might present are surely
> easier to document away than, say,
>
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>
> My point is that I think the ability to define Flash-based table objects at
> any scope with a tight and reasonable syntax warrants reconsideration of the
> Definexxx() style macros, despite the similarity to function calls. Some
> concepts are compelling enough to suggest tiny stretches of the language
> boundaries. F() is one of those, and I think tables are too.
>
> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I'm a little confused. can you explain the two approaches succinctly?
t.
On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> Anyone else have opinions on which of these two basic approaches they
> prefer? Tom, any thoughts?
>
> David
>
> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>> But consider again the macro definitions which would allow
>>
>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>
>> or
>>
>> DefineIntTable(data, 123, 456, 789);
>>
>> These pass the usefulness test with flying colors, are really easy to
>> explain, and don't have any off-putting squiggles. They solve all the
>> global/local technical difficulties I describe below, yet look comfortably
>> familiar to the beginner's eye. The objection, I believe, is that they look
>> like function calls, and function calls seem wrong floating in space at
>> global scope. But those who raise this objection do so precisely because
>> they are intimate with the language. I suspect beginners would hardly be
>> fazed. And whatever minor confusions the syntax might present are surely
>> easier to document away than, say,
>>
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> My point is that I think the ability to define Flash-based table objects at
>> any scope with a tight and reasonable syntax warrants reconsideration of the
>> Definexxx() style macros, despite the similarity to function calls. Some
>> concepts are compelling enough to suggest tiny stretches of the language
>> boundaries. F() is one of those, and I think tables are too.
>>
>> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
They both do the same thing: create an object that allows you to
access data stored in program memory (flash) using the [] array access
syntax. The question is which syntax we prefer for doing so:
DefineIntTable(data, 123, 456, 789);
Or (and here we could replace "PROGMEM" with any other word):
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Or (and again, we can use any names here):
IntData data[] = { 123, 456, 789 };
IntTable sample(data);
Any preferences?
It's apparently impossible to do any of these:
IntTable sample = { 123, 456, 789 };
IntTable sample(123, 456, 789);
IntTable sample = IntTable(123, 456, 789);
IntTable sample = IntTableData(123, 456, 789);
at least, not in way that works at global scope (outside of a
function), which seems like the most important place to be able to
define a lookup table.
David
On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
> I'm a little confused. can you explain the two approaches succinctly?
>
> t.
>
> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>
>> Anyone else have opinions on which of these two basic approaches they
>> prefer? Tom, any thoughts?
>>
>> David
>>
>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>> But consider again the macro definitions which would allow
>>>
>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>
>>> or
>>>
>>> DefineIntTable(data, 123, 456, 789);
>>>
>>> These pass the usefulness test with flying colors, are really easy to
>>> explain, and don't have any off-putting squiggles. They solve all the
>>> global/local technical difficulties I describe below, yet look comfortably
>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>> like function calls, and function calls seem wrong floating in space at
>>> global scope. But those who raise this objection do so precisely because
>>> they are intimate with the language. I suspect beginners would hardly be
>>> fazed. And whatever minor confusions the syntax might present are surely
>>> easier to document away than, say,
>>>
>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>> IntTable sample(data);
>>>
>>> My point is that I think the ability to define Flash-based table objects at
>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>> Definexxx() style macros, despite the similarity to function calls. Some
>>> concepts are compelling enough to suggest tiny stretches of the language
>>> boundaries. F() is one of those, and I think tables are too.
>>>
>>> Mikal
>
>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
These are all baby steps toward std::vector. It might be worth taking some inspiration from that direction, one way or another.
= Mike
On Mar 29, 2011, at 12:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I don't like the first version because it's unclear that data is {123, 456, 789}. It seems like data is one more element in the intTable. It should be clear that data is not the same class of thing as the things which comprise it.
The nice thing about the PROGMEM keyword is that it makes it explicit that there is something special about this array. Even if I don't yet know what an intTable is, I know there is a difference between
int data[] PROGMEM = { 123, 456, 789 };
and
int data[] = { 123, 456, 789 };
So on the whole I guess that means I prefer:
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Presumably then when I want to acces the data, I do this:
int foo = sample[1];
Serial.print(foo, DEC);
On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Tom, would you find something like
DefineIntTable(sample, { 123, 456, 789 } );
less objectionable?
In my mind there are two problems with the multiline syntax.
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
First, it seems harder to explain and conceptualize. What does all that
(apparently superfluous) typing mean? If all I want is to make an integer
table called "sample", why do I have to type 2 lines with "extra" stuff like
"data" and "PROGMEM" (or whatever)?
And pulling back that curtain on these implementation details leads to new
errors.
For example, imagine building a sine table using the above as a reference.
You know that sines are floats and not ints, so you change line 1 to
float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
So far so good, but now you also need to remember to change "IntTable" to
"FloatTable" in line 2, and you also need to make sure that the "data" in
parentheses changes to "sines" to match the array name. And of course the
killer is that
Serial.print(sines[x]);
compiles but fails miserably and inexplicably.
To my mind, its bulk and inherent fragility sink the multiline syntax. But
it's good to talk about.
Mikal
> -----Original Message-----
> From: Tom Igoe [mailto:]
> Sent: Tuesday, March 29, 2011 2:58 PM
> To: David A. Mellis
> Cc: Mikal Hart; Arduino Developers
> Subject: Re: Syntax for PROGMEM Lookup Tables
>
> I don't like the first version because it's unclear that data is {123,
> 456, 789}. It seems like data is one more element in the intTable. It
> should be clear that data is not the same class of thing as the things
> which comprise it.
>
> The nice thing about the PROGMEM keyword is that it makes it explicit
> that there is something special about this array. Even if I don't yet
> know what an intTable is, I know there is a difference between
>
> int data[] PROGMEM = { 123, 456, 789 };
>
> and
>
> int data[] = { 123, 456, 789 };
>
> So on the whole I guess that means I prefer:
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Presumably then when I want to acces the data, I do this:
>
> int foo = sample[1];
> Serial.print(foo, DEC);
>
>
> On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
>
> > They both do the same thing: create an object that allows you to
> > access data stored in program memory (flash) using the [] array
> access
> > syntax. The question is which syntax we prefer for doing so:
> >
> > DefineIntTable(data, 123, 456, 789);
> >
> > Or (and here we could replace "PROGMEM" with any other word):
> >
> > int data[] PROGMEM = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Or (and again, we can use any names here):
> >
> > IntData data[] = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Any preferences?
> >
> > It's apparently impossible to do any of these:
> >
> > IntTable sample = { 123, 456, 789 };
> > IntTable sample(123, 456, 789);
> > IntTable sample = IntTable(123, 456, 789);
> > IntTable sample = IntTableData(123, 456, 789);
> >
> > at least, not in way that works at global scope (outside of a
> > function), which seems like the most important place to be able to
> > define a lookup table.
> >
> > David
> >
> > On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <>
> wrote:
> >> I'm a little confused. can you explain the two approaches
> succinctly?
> >>
> >> t.
> >>
> >> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> >>
> >>> Anyone else have opinions on which of these two basic approaches
> they
> >>> prefer? Tom, any thoughts?
> >>>
> >>> David
> >>>
> >>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <>
> wrote:
> >>>> But consider again the macro definitions which would allow
> >>>>
> >>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998,
> 1.0);
> >>>>
> >>>> or
> >>>>
> >>>> DefineIntTable(data, 123, 456, 789);
> >>>>
> >>>> These pass the usefulness test with flying colors, are really easy
> to
> >>>> explain, and don't have any off-putting squiggles. They solve all
> the
> >>>> global/local technical difficulties I describe below, yet look
> comfortably
> >>>> familiar to the beginner's eye. The objection, I believe, is that
> they look
> >>>> like function calls, and function calls seem wrong floating in
> space at
> >>>> global scope. But those who raise this objection do so precisely
> because
> >>>> they are intimate with the language. I suspect beginners would
> hardly be
> >>>> fazed. And whatever minor confusions the syntax might present are
> surely
> >>>> easier to document away than, say,
> >>>>
> >>>>> int data[] PROGMEM = { 123, 456, 789 };
> >>>>> IntTable sample(data);
> >>>>
> >>>> My point is that I think the ability to define Flash-based table
> objects at
> >>>> any scope with a tight and reasonable syntax warrants
> reconsideration of the
> >>>> Definexxx() style macros, despite the similarity to function
> calls. Some
> >>>> concepts are compelling enough to suggest tiny stretches of the
> language
> >>>> boundaries. F() is one of those, and I think tables are too.
> >>>>
> >>>> Mikal
> >>
> >>
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
|
# 7

30-03-2011 01:11 AM
|
|
|
Anyone else have opinions on which of these two basic approaches they
prefer? Tom, any thoughts?
David
On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
> But consider again the macro definitions which would allow
>
> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>
> or
>
> DefineIntTable(data, 123, 456, 789);
>
> These pass the usefulness test with flying colors, are really easy to
> explain, and don't have any off-putting squiggles. They solve all the
> global/local technical difficulties I describe below, yet look comfortably
> familiar to the beginner's eye. The objection, I believe, is that they look
> like function calls, and function calls seem wrong floating in space at
> global scope. But those who raise this objection do so precisely because
> they are intimate with the language. I suspect beginners would hardly be
> fazed. And whatever minor confusions the syntax might present are surely
> easier to document away than, say,
>
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>
> My point is that I think the ability to define Flash-based table objects at
> any scope with a tight and reasonable syntax warrants reconsideration of the
> Definexxx() style macros, despite the similarity to function calls. Some
> concepts are compelling enough to suggest tiny stretches of the language
> boundaries. F() is one of those, and I think tables are too.
>
> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I'm a little confused. can you explain the two approaches succinctly?
t.
On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> Anyone else have opinions on which of these two basic approaches they
> prefer? Tom, any thoughts?
>
> David
>
> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>> But consider again the macro definitions which would allow
>>
>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>
>> or
>>
>> DefineIntTable(data, 123, 456, 789);
>>
>> These pass the usefulness test with flying colors, are really easy to
>> explain, and don't have any off-putting squiggles. They solve all the
>> global/local technical difficulties I describe below, yet look comfortably
>> familiar to the beginner's eye. The objection, I believe, is that they look
>> like function calls, and function calls seem wrong floating in space at
>> global scope. But those who raise this objection do so precisely because
>> they are intimate with the language. I suspect beginners would hardly be
>> fazed. And whatever minor confusions the syntax might present are surely
>> easier to document away than, say,
>>
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> My point is that I think the ability to define Flash-based table objects at
>> any scope with a tight and reasonable syntax warrants reconsideration of the
>> Definexxx() style macros, despite the similarity to function calls. Some
>> concepts are compelling enough to suggest tiny stretches of the language
>> boundaries. F() is one of those, and I think tables are too.
>>
>> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
They both do the same thing: create an object that allows you to
access data stored in program memory (flash) using the [] array access
syntax. The question is which syntax we prefer for doing so:
DefineIntTable(data, 123, 456, 789);
Or (and here we could replace "PROGMEM" with any other word):
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Or (and again, we can use any names here):
IntData data[] = { 123, 456, 789 };
IntTable sample(data);
Any preferences?
It's apparently impossible to do any of these:
IntTable sample = { 123, 456, 789 };
IntTable sample(123, 456, 789);
IntTable sample = IntTable(123, 456, 789);
IntTable sample = IntTableData(123, 456, 789);
at least, not in way that works at global scope (outside of a
function), which seems like the most important place to be able to
define a lookup table.
David
On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
> I'm a little confused. can you explain the two approaches succinctly?
>
> t.
>
> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>
>> Anyone else have opinions on which of these two basic approaches they
>> prefer? Tom, any thoughts?
>>
>> David
>>
>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>> But consider again the macro definitions which would allow
>>>
>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>
>>> or
>>>
>>> DefineIntTable(data, 123, 456, 789);
>>>
>>> These pass the usefulness test with flying colors, are really easy to
>>> explain, and don't have any off-putting squiggles. They solve all the
>>> global/local technical difficulties I describe below, yet look comfortably
>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>> like function calls, and function calls seem wrong floating in space at
>>> global scope. But those who raise this objection do so precisely because
>>> they are intimate with the language. I suspect beginners would hardly be
>>> fazed. And whatever minor confusions the syntax might present are surely
>>> easier to document away than, say,
>>>
>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>> IntTable sample(data);
>>>
>>> My point is that I think the ability to define Flash-based table objects at
>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>> Definexxx() style macros, despite the similarity to function calls. Some
>>> concepts are compelling enough to suggest tiny stretches of the language
>>> boundaries. F() is one of those, and I think tables are too.
>>>
>>> Mikal
>
>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
These are all baby steps toward std::vector. It might be worth taking some inspiration from that direction, one way or another.
= Mike
On Mar 29, 2011, at 12:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I don't like the first version because it's unclear that data is {123, 456, 789}. It seems like data is one more element in the intTable. It should be clear that data is not the same class of thing as the things which comprise it.
The nice thing about the PROGMEM keyword is that it makes it explicit that there is something special about this array. Even if I don't yet know what an intTable is, I know there is a difference between
int data[] PROGMEM = { 123, 456, 789 };
and
int data[] = { 123, 456, 789 };
So on the whole I guess that means I prefer:
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Presumably then when I want to acces the data, I do this:
int foo = sample[1];
Serial.print(foo, DEC);
On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Tom, would you find something like
DefineIntTable(sample, { 123, 456, 789 } );
less objectionable?
In my mind there are two problems with the multiline syntax.
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
First, it seems harder to explain and conceptualize. What does all that
(apparently superfluous) typing mean? If all I want is to make an integer
table called "sample", why do I have to type 2 lines with "extra" stuff like
"data" and "PROGMEM" (or whatever)?
And pulling back that curtain on these implementation details leads to new
errors.
For example, imagine building a sine table using the above as a reference.
You know that sines are floats and not ints, so you change line 1 to
float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
So far so good, but now you also need to remember to change "IntTable" to
"FloatTable" in line 2, and you also need to make sure that the "data" in
parentheses changes to "sines" to match the array name. And of course the
killer is that
Serial.print(sines[x]);
compiles but fails miserably and inexplicably.
To my mind, its bulk and inherent fragility sink the multiline syntax. But
it's good to talk about.
Mikal
> -----Original Message-----
> From: Tom Igoe [mailto:]
> Sent: Tuesday, March 29, 2011 2:58 PM
> To: David A. Mellis
> Cc: Mikal Hart; Arduino Developers
> Subject: Re: Syntax for PROGMEM Lookup Tables
>
> I don't like the first version because it's unclear that data is {123,
> 456, 789}. It seems like data is one more element in the intTable. It
> should be clear that data is not the same class of thing as the things
> which comprise it.
>
> The nice thing about the PROGMEM keyword is that it makes it explicit
> that there is something special about this array. Even if I don't yet
> know what an intTable is, I know there is a difference between
>
> int data[] PROGMEM = { 123, 456, 789 };
>
> and
>
> int data[] = { 123, 456, 789 };
>
> So on the whole I guess that means I prefer:
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Presumably then when I want to acces the data, I do this:
>
> int foo = sample[1];
> Serial.print(foo, DEC);
>
>
> On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
>
> > They both do the same thing: create an object that allows you to
> > access data stored in program memory (flash) using the [] array
> access
> > syntax. The question is which syntax we prefer for doing so:
> >
> > DefineIntTable(data, 123, 456, 789);
> >
> > Or (and here we could replace "PROGMEM" with any other word):
> >
> > int data[] PROGMEM = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Or (and again, we can use any names here):
> >
> > IntData data[] = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Any preferences?
> >
> > It's apparently impossible to do any of these:
> >
> > IntTable sample = { 123, 456, 789 };
> > IntTable sample(123, 456, 789);
> > IntTable sample = IntTable(123, 456, 789);
> > IntTable sample = IntTableData(123, 456, 789);
> >
> > at least, not in way that works at global scope (outside of a
> > function), which seems like the most important place to be able to
> > define a lookup table.
> >
> > David
> >
> > On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <>
> wrote:
> >> I'm a little confused. can you explain the two approaches
> succinctly?
> >>
> >> t.
> >>
> >> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> >>
> >>> Anyone else have opinions on which of these two basic approaches
> they
> >>> prefer? Tom, any thoughts?
> >>>
> >>> David
> >>>
> >>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <>
> wrote:
> >>>> But consider again the macro definitions which would allow
> >>>>
> >>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998,
> 1.0);
> >>>>
> >>>> or
> >>>>
> >>>> DefineIntTable(data, 123, 456, 789);
> >>>>
> >>>> These pass the usefulness test with flying colors, are really easy
> to
> >>>> explain, and don't have any off-putting squiggles. They solve all
> the
> >>>> global/local technical difficulties I describe below, yet look
> comfortably
> >>>> familiar to the beginner's eye. The objection, I believe, is that
> they look
> >>>> like function calls, and function calls seem wrong floating in
> space at
> >>>> global scope. But those who raise this objection do so precisely
> because
> >>>> they are intimate with the language. I suspect beginners would
> hardly be
> >>>> fazed. And whatever minor confusions the syntax might present are
> surely
> >>>> easier to document away than, say,
> >>>>
> >>>>> int data[] PROGMEM = { 123, 456, 789 };
> >>>>> IntTable sample(data);
> >>>>
> >>>> My point is that I think the ability to define Flash-based table
> objects at
> >>>> any scope with a tight and reasonable syntax warrants
> reconsideration of the
> >>>> Definexxx() style macros, despite the similarity to function
> calls. Some
> >>>> concepts are compelling enough to suggest tiny stretches of the
> language
> >>>> boundaries. F() is one of those, and I think tables are too.
> >>>>
> >>>> Mikal
> >>
> >>
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
On Mar 29, 2011, at 7:55 PM, Mikal Hart wrote:
> Tom, would you find something like
>
> DefineIntTable(sample, { 123, 456, 789 } );
>
> less objectionable?
No, it'd be more objectionable to me. It introduces a new structure of punctuation that adds confusion without clarifying anything. It's almost as bad as my least favorite in Processing, Serial.list()[0]. Way too much packed in there. Which is also why we need a print function for IPAddresses, by the way.
>
> First, it seems harder to explain and conceptualize. What does all that
> (apparently superfluous) typing mean? If all I want is to make an integer
> table called "sample", why do I have to type 2 lines with "extra" stuff like
> "data" and "PROGMEM" (or whatever)?
Actually, more typing is usually easier to explain and conceptualize. Terseness is great for experienced programmers, but for beginners, and especially beginners who don't necessarily want to be programers, verboseness actually works better. You don't have to remember what things mean, you just read the word. And when the punctuation is simple and clearly defined, even better. Multiple brackets make things worse, and grammar forms that do different things but look the same are a disaster.
>
> And pulling back that curtain on these implementation details leads to new
> errors.
>
> For example, imagine building a sine table using the above as a reference.
> You know that sines are floats and not ints, so you change line 1 to
>
> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>
> So far so good, but now you also need to remember to change "IntTable" to
> "FloatTable" in line 2, and you also need to make sure that the "data" in
> parentheses changes to "sines" to match the array name.
That's not such a problem, because there's a parallelism to it. It makes sense that I build an intTable with ints and a floatTable with floats. I don't think it's always necessary to hide things to make them simple. You have to give people credit for intelligence, even when they lack knowledge. A clear grammar that they can figure out is better than a simple one that's harder to expand.
> And of course thekiller is that
> Serial.print(sines[x]);
>
> compiles but fails miserably and inexplicably.
That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
>
>
> To my mind, its bulk and inherent fragility sink the multiline syntax. But
> it's good to talk about.
I'm okay with a single line syntax if it's clearly different from other structures, and grammatically and syntatically straightforward, and reveals how it works through its structure. Dave already shot down some of the possibilities I'd consider, so I won't bother with them.
The two-line PROGMEM syntax isn't perfect, I'll agree. But I think it's better than any of the three options presented so far. I'm happy to see other options, though.
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
|
# 8

30-03-2011 09:08 AM
|
|
|
Anyone else have opinions on which of these two basic approaches they
prefer? Tom, any thoughts?
David
On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
> But consider again the macro definitions which would allow
>
> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>
> or
>
> DefineIntTable(data, 123, 456, 789);
>
> These pass the usefulness test with flying colors, are really easy to
> explain, and don't have any off-putting squiggles. They solve all the
> global/local technical difficulties I describe below, yet look comfortably
> familiar to the beginner's eye. The objection, I believe, is that they look
> like function calls, and function calls seem wrong floating in space at
> global scope. But those who raise this objection do so precisely because
> they are intimate with the language. I suspect beginners would hardly be
> fazed. And whatever minor confusions the syntax might present are surely
> easier to document away than, say,
>
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>
> My point is that I think the ability to define Flash-based table objects at
> any scope with a tight and reasonable syntax warrants reconsideration of the
> Definexxx() style macros, despite the similarity to function calls. Some
> concepts are compelling enough to suggest tiny stretches of the language
> boundaries. F() is one of those, and I think tables are too.
>
> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I'm a little confused. can you explain the two approaches succinctly?
t.
On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> Anyone else have opinions on which of these two basic approaches they
> prefer? Tom, any thoughts?
>
> David
>
> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>> But consider again the macro definitions which would allow
>>
>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>
>> or
>>
>> DefineIntTable(data, 123, 456, 789);
>>
>> These pass the usefulness test with flying colors, are really easy to
>> explain, and don't have any off-putting squiggles. They solve all the
>> global/local technical difficulties I describe below, yet look comfortably
>> familiar to the beginner's eye. The objection, I believe, is that they look
>> like function calls, and function calls seem wrong floating in space at
>> global scope. But those who raise this objection do so precisely because
>> they are intimate with the language. I suspect beginners would hardly be
>> fazed. And whatever minor confusions the syntax might present are surely
>> easier to document away than, say,
>>
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> My point is that I think the ability to define Flash-based table objects at
>> any scope with a tight and reasonable syntax warrants reconsideration of the
>> Definexxx() style macros, despite the similarity to function calls. Some
>> concepts are compelling enough to suggest tiny stretches of the language
>> boundaries. F() is one of those, and I think tables are too.
>>
>> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
They both do the same thing: create an object that allows you to
access data stored in program memory (flash) using the [] array access
syntax. The question is which syntax we prefer for doing so:
DefineIntTable(data, 123, 456, 789);
Or (and here we could replace "PROGMEM" with any other word):
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Or (and again, we can use any names here):
IntData data[] = { 123, 456, 789 };
IntTable sample(data);
Any preferences?
It's apparently impossible to do any of these:
IntTable sample = { 123, 456, 789 };
IntTable sample(123, 456, 789);
IntTable sample = IntTable(123, 456, 789);
IntTable sample = IntTableData(123, 456, 789);
at least, not in way that works at global scope (outside of a
function), which seems like the most important place to be able to
define a lookup table.
David
On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
> I'm a little confused. can you explain the two approaches succinctly?
>
> t.
>
> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>
>> Anyone else have opinions on which of these two basic approaches they
>> prefer? Tom, any thoughts?
>>
>> David
>>
>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>> But consider again the macro definitions which would allow
>>>
>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>
>>> or
>>>
>>> DefineIntTable(data, 123, 456, 789);
>>>
>>> These pass the usefulness test with flying colors, are really easy to
>>> explain, and don't have any off-putting squiggles. They solve all the
>>> global/local technical difficulties I describe below, yet look comfortably
>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>> like function calls, and function calls seem wrong floating in space at
>>> global scope. But those who raise this objection do so precisely because
>>> they are intimate with the language. I suspect beginners would hardly be
>>> fazed. And whatever minor confusions the syntax might present are surely
>>> easier to document away than, say,
>>>
>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>> IntTable sample(data);
>>>
>>> My point is that I think the ability to define Flash-based table objects at
>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>> Definexxx() style macros, despite the similarity to function calls. Some
>>> concepts are compelling enough to suggest tiny stretches of the language
>>> boundaries. F() is one of those, and I think tables are too.
>>>
>>> Mikal
>
>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
These are all baby steps toward std::vector. It might be worth taking some inspiration from that direction, one way or another.
= Mike
On Mar 29, 2011, at 12:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I don't like the first version because it's unclear that data is {123, 456, 789}. It seems like data is one more element in the intTable. It should be clear that data is not the same class of thing as the things which comprise it.
The nice thing about the PROGMEM keyword is that it makes it explicit that there is something special about this array. Even if I don't yet know what an intTable is, I know there is a difference between
int data[] PROGMEM = { 123, 456, 789 };
and
int data[] = { 123, 456, 789 };
So on the whole I guess that means I prefer:
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Presumably then when I want to acces the data, I do this:
int foo = sample[1];
Serial.print(foo, DEC);
On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Tom, would you find something like
DefineIntTable(sample, { 123, 456, 789 } );
less objectionable?
In my mind there are two problems with the multiline syntax.
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
First, it seems harder to explain and conceptualize. What does all that
(apparently superfluous) typing mean? If all I want is to make an integer
table called "sample", why do I have to type 2 lines with "extra" stuff like
"data" and "PROGMEM" (or whatever)?
And pulling back that curtain on these implementation details leads to new
errors.
For example, imagine building a sine table using the above as a reference.
You know that sines are floats and not ints, so you change line 1 to
float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
So far so good, but now you also need to remember to change "IntTable" to
"FloatTable" in line 2, and you also need to make sure that the "data" in
parentheses changes to "sines" to match the array name. And of course the
killer is that
Serial.print(sines[x]);
compiles but fails miserably and inexplicably.
To my mind, its bulk and inherent fragility sink the multiline syntax. But
it's good to talk about.
Mikal
> -----Original Message-----
> From: Tom Igoe [mailto:]
> Sent: Tuesday, March 29, 2011 2:58 PM
> To: David A. Mellis
> Cc: Mikal Hart; Arduino Developers
> Subject: Re: Syntax for PROGMEM Lookup Tables
>
> I don't like the first version because it's unclear that data is {123,
> 456, 789}. It seems like data is one more element in the intTable. It
> should be clear that data is not the same class of thing as the things
> which comprise it.
>
> The nice thing about the PROGMEM keyword is that it makes it explicit
> that there is something special about this array. Even if I don't yet
> know what an intTable is, I know there is a difference between
>
> int data[] PROGMEM = { 123, 456, 789 };
>
> and
>
> int data[] = { 123, 456, 789 };
>
> So on the whole I guess that means I prefer:
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Presumably then when I want to acces the data, I do this:
>
> int foo = sample[1];
> Serial.print(foo, DEC);
>
>
> On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
>
> > They both do the same thing: create an object that allows you to
> > access data stored in program memory (flash) using the [] array
> access
> > syntax. The question is which syntax we prefer for doing so:
> >
> > DefineIntTable(data, 123, 456, 789);
> >
> > Or (and here we could replace "PROGMEM" with any other word):
> >
> > int data[] PROGMEM = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Or (and again, we can use any names here):
> >
> > IntData data[] = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Any preferences?
> >
> > It's apparently impossible to do any of these:
> >
> > IntTable sample = { 123, 456, 789 };
> > IntTable sample(123, 456, 789);
> > IntTable sample = IntTable(123, 456, 789);
> > IntTable sample = IntTableData(123, 456, 789);
> >
> > at least, not in way that works at global scope (outside of a
> > function), which seems like the most important place to be able to
> > define a lookup table.
> >
> > David
> >
> > On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <>
> wrote:
> >> I'm a little confused. can you explain the two approaches
> succinctly?
> >>
> >> t.
> >>
> >> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> >>
> >>> Anyone else have opinions on which of these two basic approaches
> they
> >>> prefer? Tom, any thoughts?
> >>>
> >>> David
> >>>
> >>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <>
> wrote:
> >>>> But consider again the macro definitions which would allow
> >>>>
> >>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998,
> 1.0);
> >>>>
> >>>> or
> >>>>
> >>>> DefineIntTable(data, 123, 456, 789);
> >>>>
> >>>> These pass the usefulness test with flying colors, are really easy
> to
> >>>> explain, and don't have any off-putting squiggles. They solve all
> the
> >>>> global/local technical difficulties I describe below, yet look
> comfortably
> >>>> familiar to the beginner's eye. The objection, I believe, is that
> they look
> >>>> like function calls, and function calls seem wrong floating in
> space at
> >>>> global scope. But those who raise this objection do so precisely
> because
> >>>> they are intimate with the language. I suspect beginners would
> hardly be
> >>>> fazed. And whatever minor confusions the syntax might present are
> surely
> >>>> easier to document away than, say,
> >>>>
> >>>>> int data[] PROGMEM = { 123, 456, 789 };
> >>>>> IntTable sample(data);
> >>>>
> >>>> My point is that I think the ability to define Flash-based table
> objects at
> >>>> any scope with a tight and reasonable syntax warrants
> reconsideration of the
> >>>> Definexxx() style macros, despite the similarity to function
> calls. Some
> >>>> concepts are compelling enough to suggest tiny stretches of the
> language
> >>>> boundaries. F() is one of those, and I think tables are too.
> >>>>
> >>>> Mikal
> >>
> >>
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
On Mar 29, 2011, at 7:55 PM, Mikal Hart wrote:
> Tom, would you find something like
>
> DefineIntTable(sample, { 123, 456, 789 } );
>
> less objectionable?
No, it'd be more objectionable to me. It introduces a new structure of punctuation that adds confusion without clarifying anything. It's almost as bad as my least favorite in Processing, Serial.list()[0]. Way too much packed in there. Which is also why we need a print function for IPAddresses, by the way.
>
> First, it seems harder to explain and conceptualize. What does all that
> (apparently superfluous) typing mean? If all I want is to make an integer
> table called "sample", why do I have to type 2 lines with "extra" stuff like
> "data" and "PROGMEM" (or whatever)?
Actually, more typing is usually easier to explain and conceptualize. Terseness is great for experienced programmers, but for beginners, and especially beginners who don't necessarily want to be programers, verboseness actually works better. You don't have to remember what things mean, you just read the word. And when the punctuation is simple and clearly defined, even better. Multiple brackets make things worse, and grammar forms that do different things but look the same are a disaster.
>
> And pulling back that curtain on these implementation details leads to new
> errors.
>
> For example, imagine building a sine table using the above as a reference.
> You know that sines are floats and not ints, so you change line 1 to
>
> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>
> So far so good, but now you also need to remember to change "IntTable" to
> "FloatTable" in line 2, and you also need to make sure that the "data" in
> parentheses changes to "sines" to match the array name.
That's not such a problem, because there's a parallelism to it. It makes sense that I build an intTable with ints and a floatTable with floats. I don't think it's always necessary to hide things to make them simple. You have to give people credit for intelligence, even when they lack knowledge. A clear grammar that they can figure out is better than a simple one that's harder to expand.
> And of course thekiller is that
> Serial.print(sines[x]);
>
> compiles but fails miserably and inexplicably.
That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
>
>
> To my mind, its bulk and inherent fragility sink the multiline syntax. But
> it's good to talk about.
I'm okay with a single line syntax if it's clearly different from other structures, and grammatically and syntatically straightforward, and reveals how it works through its structure. Dave already shot down some of the possibilities I'd consider, so I won't bother with them.
The two-line PROGMEM syntax isn't perfect, I'll agree. But I think it's better than any of the three options presented so far. I'm happy to see other options, though.
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
>> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>> And of course thekiller is that
>> Serial.print(sines[x]);
>>
>> compiles but fails miserably and inexplicably.
> That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
The compiler does not know where "sines" will be placed in memory; the
linker determines that. The compiler generates the executable code for
this...
Serial.print(sines[x]);
...but leaves a place-holder for the address of "sines". The linker
substitutes the place-holder for the actual address of "sines".
The compiler has absolutely no awareness of PROGMEM data^1 . It sees
"sines" as an ordinary array of floats. The code generated by the
compiler for the "print" reads the value from SRAM. The linker puts
"sines" in Flash and substitutes the place-holder for the address.
Basically, "sines" is stored in Flash but the code reads from SRAM.
^1 Which is why it is impossible to devise a more user friendly syntax
for PROGMEM data.
- Brian
|
# 9

31-03-2011 02:47 AM
|
|
|
Anyone else have opinions on which of these two basic approaches they
prefer? Tom, any thoughts?
David
On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
> But consider again the macro definitions which would allow
>
> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>
> or
>
> DefineIntTable(data, 123, 456, 789);
>
> These pass the usefulness test with flying colors, are really easy to
> explain, and don't have any off-putting squiggles. They solve all the
> global/local technical difficulties I describe below, yet look comfortably
> familiar to the beginner's eye. The objection, I believe, is that they look
> like function calls, and function calls seem wrong floating in space at
> global scope. But those who raise this objection do so precisely because
> they are intimate with the language. I suspect beginners would hardly be
> fazed. And whatever minor confusions the syntax might present are surely
> easier to document away than, say,
>
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>
> My point is that I think the ability to define Flash-based table objects at
> any scope with a tight and reasonable syntax warrants reconsideration of the
> Definexxx() style macros, despite the similarity to function calls. Some
> concepts are compelling enough to suggest tiny stretches of the language
> boundaries. F() is one of those, and I think tables are too.
>
> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I'm a little confused. can you explain the two approaches succinctly?
t.
On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> Anyone else have opinions on which of these two basic approaches they
> prefer? Tom, any thoughts?
>
> David
>
> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>> But consider again the macro definitions which would allow
>>
>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>
>> or
>>
>> DefineIntTable(data, 123, 456, 789);
>>
>> These pass the usefulness test with flying colors, are really easy to
>> explain, and don't have any off-putting squiggles. They solve all the
>> global/local technical difficulties I describe below, yet look comfortably
>> familiar to the beginner's eye. The objection, I believe, is that they look
>> like function calls, and function calls seem wrong floating in space at
>> global scope. But those who raise this objection do so precisely because
>> they are intimate with the language. I suspect beginners would hardly be
>> fazed. And whatever minor confusions the syntax might present are surely
>> easier to document away than, say,
>>
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> My point is that I think the ability to define Flash-based table objects at
>> any scope with a tight and reasonable syntax warrants reconsideration of the
>> Definexxx() style macros, despite the similarity to function calls. Some
>> concepts are compelling enough to suggest tiny stretches of the language
>> boundaries. F() is one of those, and I think tables are too.
>>
>> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
They both do the same thing: create an object that allows you to
access data stored in program memory (flash) using the [] array access
syntax. The question is which syntax we prefer for doing so:
DefineIntTable(data, 123, 456, 789);
Or (and here we could replace "PROGMEM" with any other word):
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Or (and again, we can use any names here):
IntData data[] = { 123, 456, 789 };
IntTable sample(data);
Any preferences?
It's apparently impossible to do any of these:
IntTable sample = { 123, 456, 789 };
IntTable sample(123, 456, 789);
IntTable sample = IntTable(123, 456, 789);
IntTable sample = IntTableData(123, 456, 789);
at least, not in way that works at global scope (outside of a
function), which seems like the most important place to be able to
define a lookup table.
David
On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
> I'm a little confused. can you explain the two approaches succinctly?
>
> t.
>
> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>
>> Anyone else have opinions on which of these two basic approaches they
>> prefer? Tom, any thoughts?
>>
>> David
>>
>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>> But consider again the macro definitions which would allow
>>>
>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>
>>> or
>>>
>>> DefineIntTable(data, 123, 456, 789);
>>>
>>> These pass the usefulness test with flying colors, are really easy to
>>> explain, and don't have any off-putting squiggles. They solve all the
>>> global/local technical difficulties I describe below, yet look comfortably
>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>> like function calls, and function calls seem wrong floating in space at
>>> global scope. But those who raise this objection do so precisely because
>>> they are intimate with the language. I suspect beginners would hardly be
>>> fazed. And whatever minor confusions the syntax might present are surely
>>> easier to document away than, say,
>>>
>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>> IntTable sample(data);
>>>
>>> My point is that I think the ability to define Flash-based table objects at
>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>> Definexxx() style macros, despite the similarity to function calls. Some
>>> concepts are compelling enough to suggest tiny stretches of the language
>>> boundaries. F() is one of those, and I think tables are too.
>>>
>>> Mikal
>
>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
These are all baby steps toward std::vector. It might be worth taking some inspiration from that direction, one way or another.
= Mike
On Mar 29, 2011, at 12:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I don't like the first version because it's unclear that data is {123, 456, 789}. It seems like data is one more element in the intTable. It should be clear that data is not the same class of thing as the things which comprise it.
The nice thing about the PROGMEM keyword is that it makes it explicit that there is something special about this array. Even if I don't yet know what an intTable is, I know there is a difference between
int data[] PROGMEM = { 123, 456, 789 };
and
int data[] = { 123, 456, 789 };
So on the whole I guess that means I prefer:
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Presumably then when I want to acces the data, I do this:
int foo = sample[1];
Serial.print(foo, DEC);
On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Tom, would you find something like
DefineIntTable(sample, { 123, 456, 789 } );
less objectionable?
In my mind there are two problems with the multiline syntax.
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
First, it seems harder to explain and conceptualize. What does all that
(apparently superfluous) typing mean? If all I want is to make an integer
table called "sample", why do I have to type 2 lines with "extra" stuff like
"data" and "PROGMEM" (or whatever)?
And pulling back that curtain on these implementation details leads to new
errors.
For example, imagine building a sine table using the above as a reference.
You know that sines are floats and not ints, so you change line 1 to
float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
So far so good, but now you also need to remember to change "IntTable" to
"FloatTable" in line 2, and you also need to make sure that the "data" in
parentheses changes to "sines" to match the array name. And of course the
killer is that
Serial.print(sines[x]);
compiles but fails miserably and inexplicably.
To my mind, its bulk and inherent fragility sink the multiline syntax. But
it's good to talk about.
Mikal
> -----Original Message-----
> From: Tom Igoe [mailto:]
> Sent: Tuesday, March 29, 2011 2:58 PM
> To: David A. Mellis
> Cc: Mikal Hart; Arduino Developers
> Subject: Re: Syntax for PROGMEM Lookup Tables
>
> I don't like the first version because it's unclear that data is {123,
> 456, 789}. It seems like data is one more element in the intTable. It
> should be clear that data is not the same class of thing as the things
> which comprise it.
>
> The nice thing about the PROGMEM keyword is that it makes it explicit
> that there is something special about this array. Even if I don't yet
> know what an intTable is, I know there is a difference between
>
> int data[] PROGMEM = { 123, 456, 789 };
>
> and
>
> int data[] = { 123, 456, 789 };
>
> So on the whole I guess that means I prefer:
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Presumably then when I want to acces the data, I do this:
>
> int foo = sample[1];
> Serial.print(foo, DEC);
>
>
> On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
>
> > They both do the same thing: create an object that allows you to
> > access data stored in program memory (flash) using the [] array
> access
> > syntax. The question is which syntax we prefer for doing so:
> >
> > DefineIntTable(data, 123, 456, 789);
> >
> > Or (and here we could replace "PROGMEM" with any other word):
> >
> > int data[] PROGMEM = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Or (and again, we can use any names here):
> >
> > IntData data[] = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Any preferences?
> >
> > It's apparently impossible to do any of these:
> >
> > IntTable sample = { 123, 456, 789 };
> > IntTable sample(123, 456, 789);
> > IntTable sample = IntTable(123, 456, 789);
> > IntTable sample = IntTableData(123, 456, 789);
> >
> > at least, not in way that works at global scope (outside of a
> > function), which seems like the most important place to be able to
> > define a lookup table.
> >
> > David
> >
> > On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <>
> wrote:
> >> I'm a little confused. can you explain the two approaches
> succinctly?
> >>
> >> t.
> >>
> >> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> >>
> >>> Anyone else have opinions on which of these two basic approaches
> they
> >>> prefer? Tom, any thoughts?
> >>>
> >>> David
> >>>
> >>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <>
> wrote:
> >>>> But consider again the macro definitions which would allow
> >>>>
> >>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998,
> 1.0);
> >>>>
> >>>> or
> >>>>
> >>>> DefineIntTable(data, 123, 456, 789);
> >>>>
> >>>> These pass the usefulness test with flying colors, are really easy
> to
> >>>> explain, and don't have any off-putting squiggles. They solve all
> the
> >>>> global/local technical difficulties I describe below, yet look
> comfortably
> >>>> familiar to the beginner's eye. The objection, I believe, is that
> they look
> >>>> like function calls, and function calls seem wrong floating in
> space at
> >>>> global scope. But those who raise this objection do so precisely
> because
> >>>> they are intimate with the language. I suspect beginners would
> hardly be
> >>>> fazed. And whatever minor confusions the syntax might present are
> surely
> >>>> easier to document away than, say,
> >>>>
> >>>>> int data[] PROGMEM = { 123, 456, 789 };
> >>>>> IntTable sample(data);
> >>>>
> >>>> My point is that I think the ability to define Flash-based table
> objects at
> >>>> any scope with a tight and reasonable syntax warrants
> reconsideration of the
> >>>> Definexxx() style macros, despite the similarity to function
> calls. Some
> >>>> concepts are compelling enough to suggest tiny stretches of the
> language
> >>>> boundaries. F() is one of those, and I think tables are too.
> >>>>
> >>>> Mikal
> >>
> >>
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
On Mar 29, 2011, at 7:55 PM, Mikal Hart wrote:
> Tom, would you find something like
>
> DefineIntTable(sample, { 123, 456, 789 } );
>
> less objectionable?
No, it'd be more objectionable to me. It introduces a new structure of punctuation that adds confusion without clarifying anything. It's almost as bad as my least favorite in Processing, Serial.list()[0]. Way too much packed in there. Which is also why we need a print function for IPAddresses, by the way.
>
> First, it seems harder to explain and conceptualize. What does all that
> (apparently superfluous) typing mean? If all I want is to make an integer
> table called "sample", why do I have to type 2 lines with "extra" stuff like
> "data" and "PROGMEM" (or whatever)?
Actually, more typing is usually easier to explain and conceptualize. Terseness is great for experienced programmers, but for beginners, and especially beginners who don't necessarily want to be programers, verboseness actually works better. You don't have to remember what things mean, you just read the word. And when the punctuation is simple and clearly defined, even better. Multiple brackets make things worse, and grammar forms that do different things but look the same are a disaster.
>
> And pulling back that curtain on these implementation details leads to new
> errors.
>
> For example, imagine building a sine table using the above as a reference.
> You know that sines are floats and not ints, so you change line 1 to
>
> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>
> So far so good, but now you also need to remember to change "IntTable" to
> "FloatTable" in line 2, and you also need to make sure that the "data" in
> parentheses changes to "sines" to match the array name.
That's not such a problem, because there's a parallelism to it. It makes sense that I build an intTable with ints and a floatTable with floats. I don't think it's always necessary to hide things to make them simple. You have to give people credit for intelligence, even when they lack knowledge. A clear grammar that they can figure out is better than a simple one that's harder to expand.
> And of course thekiller is that
> Serial.print(sines[x]);
>
> compiles but fails miserably and inexplicably.
That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
>
>
> To my mind, its bulk and inherent fragility sink the multiline syntax. But
> it's good to talk about.
I'm okay with a single line syntax if it's clearly different from other structures, and grammatically and syntatically straightforward, and reveals how it works through its structure. Dave already shot down some of the possibilities I'd consider, so I won't bother with them.
The two-line PROGMEM syntax isn't perfect, I'll agree. But I think it's better than any of the three options presented so far. I'm happy to see other options, though.
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
>> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>> And of course thekiller is that
>> Serial.print(sines[x]);
>>
>> compiles but fails miserably and inexplicably.
> That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
The compiler does not know where "sines" will be placed in memory; the
linker determines that. The compiler generates the executable code for
this...
Serial.print(sines[x]);
...but leaves a place-holder for the address of "sines". The linker
substitutes the place-holder for the actual address of "sines".
The compiler has absolutely no awareness of PROGMEM data^1 . It sees
"sines" as an ordinary array of floats. The code generated by the
compiler for the "print" reads the value from SRAM. The linker puts
"sines" in Flash and substitutes the place-holder for the address.
Basically, "sines" is stored in Flash but the code reads from SRAM.
^1 Which is why it is impossible to devise a more user friendly syntax
for PROGMEM data.
- Brian
On 30/03/2011, at 3:22 , David A. Mellis wrote:
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
One way to mitigate this would be by convention, something like:
IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
IntTable sample(sample_PROGMEM_reference);
Another possible defence of the latter format would be
typedef IntData struct { int value; }
That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
Enjoy,
Peter.
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
|
# 10

31-03-2011 01:36 PM
|
|
|
Anyone else have opinions on which of these two basic approaches they
prefer? Tom, any thoughts?
David
On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
> But consider again the macro definitions which would allow
>
> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>
> or
>
> DefineIntTable(data, 123, 456, 789);
>
> These pass the usefulness test with flying colors, are really easy to
> explain, and don't have any off-putting squiggles. They solve all the
> global/local technical difficulties I describe below, yet look comfortably
> familiar to the beginner's eye. The objection, I believe, is that they look
> like function calls, and function calls seem wrong floating in space at
> global scope. But those who raise this objection do so precisely because
> they are intimate with the language. I suspect beginners would hardly be
> fazed. And whatever minor confusions the syntax might present are surely
> easier to document away than, say,
>
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>
> My point is that I think the ability to define Flash-based table objects at
> any scope with a tight and reasonable syntax warrants reconsideration of the
> Definexxx() style macros, despite the similarity to function calls. Some
> concepts are compelling enough to suggest tiny stretches of the language
> boundaries. F() is one of those, and I think tables are too.
>
> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I'm a little confused. can you explain the two approaches succinctly?
t.
On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> Anyone else have opinions on which of these two basic approaches they
> prefer? Tom, any thoughts?
>
> David
>
> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>> But consider again the macro definitions which would allow
>>
>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>
>> or
>>
>> DefineIntTable(data, 123, 456, 789);
>>
>> These pass the usefulness test with flying colors, are really easy to
>> explain, and don't have any off-putting squiggles. They solve all the
>> global/local technical difficulties I describe below, yet look comfortably
>> familiar to the beginner's eye. The objection, I believe, is that they look
>> like function calls, and function calls seem wrong floating in space at
>> global scope. But those who raise this objection do so precisely because
>> they are intimate with the language. I suspect beginners would hardly be
>> fazed. And whatever minor confusions the syntax might present are surely
>> easier to document away than, say,
>>
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> My point is that I think the ability to define Flash-based table objects at
>> any scope with a tight and reasonable syntax warrants reconsideration of the
>> Definexxx() style macros, despite the similarity to function calls. Some
>> concepts are compelling enough to suggest tiny stretches of the language
>> boundaries. F() is one of those, and I think tables are too.
>>
>> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
They both do the same thing: create an object that allows you to
access data stored in program memory (flash) using the [] array access
syntax. The question is which syntax we prefer for doing so:
DefineIntTable(data, 123, 456, 789);
Or (and here we could replace "PROGMEM" with any other word):
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Or (and again, we can use any names here):
IntData data[] = { 123, 456, 789 };
IntTable sample(data);
Any preferences?
It's apparently impossible to do any of these:
IntTable sample = { 123, 456, 789 };
IntTable sample(123, 456, 789);
IntTable sample = IntTable(123, 456, 789);
IntTable sample = IntTableData(123, 456, 789);
at least, not in way that works at global scope (outside of a
function), which seems like the most important place to be able to
define a lookup table.
David
On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
> I'm a little confused. can you explain the two approaches succinctly?
>
> t.
>
> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>
>> Anyone else have opinions on which of these two basic approaches they
>> prefer? Tom, any thoughts?
>>
>> David
>>
>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>> But consider again the macro definitions which would allow
>>>
>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>
>>> or
>>>
>>> DefineIntTable(data, 123, 456, 789);
>>>
>>> These pass the usefulness test with flying colors, are really easy to
>>> explain, and don't have any off-putting squiggles. They solve all the
>>> global/local technical difficulties I describe below, yet look comfortably
>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>> like function calls, and function calls seem wrong floating in space at
>>> global scope. But those who raise this objection do so precisely because
>>> they are intimate with the language. I suspect beginners would hardly be
>>> fazed. And whatever minor confusions the syntax might present are surely
>>> easier to document away than, say,
>>>
>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>> IntTable sample(data);
>>>
>>> My point is that I think the ability to define Flash-based table objects at
>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>> Definexxx() style macros, despite the similarity to function calls. Some
>>> concepts are compelling enough to suggest tiny stretches of the language
>>> boundaries. F() is one of those, and I think tables are too.
>>>
>>> Mikal
>
>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
These are all baby steps toward std::vector. It might be worth taking some inspiration from that direction, one way or another.
= Mike
On Mar 29, 2011, at 12:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I don't like the first version because it's unclear that data is {123, 456, 789}. It seems like data is one more element in the intTable. It should be clear that data is not the same class of thing as the things which comprise it.
The nice thing about the PROGMEM keyword is that it makes it explicit that there is something special about this array. Even if I don't yet know what an intTable is, I know there is a difference between
int data[] PROGMEM = { 123, 456, 789 };
and
int data[] = { 123, 456, 789 };
So on the whole I guess that means I prefer:
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Presumably then when I want to acces the data, I do this:
int foo = sample[1];
Serial.print(foo, DEC);
On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Tom, would you find something like
DefineIntTable(sample, { 123, 456, 789 } );
less objectionable?
In my mind there are two problems with the multiline syntax.
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
First, it seems harder to explain and conceptualize. What does all that
(apparently superfluous) typing mean? If all I want is to make an integer
table called "sample", why do I have to type 2 lines with "extra" stuff like
"data" and "PROGMEM" (or whatever)?
And pulling back that curtain on these implementation details leads to new
errors.
For example, imagine building a sine table using the above as a reference.
You know that sines are floats and not ints, so you change line 1 to
float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
So far so good, but now you also need to remember to change "IntTable" to
"FloatTable" in line 2, and you also need to make sure that the "data" in
parentheses changes to "sines" to match the array name. And of course the
killer is that
Serial.print(sines[x]);
compiles but fails miserably and inexplicably.
To my mind, its bulk and inherent fragility sink the multiline syntax. But
it's good to talk about.
Mikal
> -----Original Message-----
> From: Tom Igoe [mailto:]
> Sent: Tuesday, March 29, 2011 2:58 PM
> To: David A. Mellis
> Cc: Mikal Hart; Arduino Developers
> Subject: Re: Syntax for PROGMEM Lookup Tables
>
> I don't like the first version because it's unclear that data is {123,
> 456, 789}. It seems like data is one more element in the intTable. It
> should be clear that data is not the same class of thing as the things
> which comprise it.
>
> The nice thing about the PROGMEM keyword is that it makes it explicit
> that there is something special about this array. Even if I don't yet
> know what an intTable is, I know there is a difference between
>
> int data[] PROGMEM = { 123, 456, 789 };
>
> and
>
> int data[] = { 123, 456, 789 };
>
> So on the whole I guess that means I prefer:
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Presumably then when I want to acces the data, I do this:
>
> int foo = sample[1];
> Serial.print(foo, DEC);
>
>
> On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
>
> > They both do the same thing: create an object that allows you to
> > access data stored in program memory (flash) using the [] array
> access
> > syntax. The question is which syntax we prefer for doing so:
> >
> > DefineIntTable(data, 123, 456, 789);
> >
> > Or (and here we could replace "PROGMEM" with any other word):
> >
> > int data[] PROGMEM = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Or (and again, we can use any names here):
> >
> > IntData data[] = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Any preferences?
> >
> > It's apparently impossible to do any of these:
> >
> > IntTable sample = { 123, 456, 789 };
> > IntTable sample(123, 456, 789);
> > IntTable sample = IntTable(123, 456, 789);
> > IntTable sample = IntTableData(123, 456, 789);
> >
> > at least, not in way that works at global scope (outside of a
> > function), which seems like the most important place to be able to
> > define a lookup table.
> >
> > David
> >
> > On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <>
> wrote:
> >> I'm a little confused. can you explain the two approaches
> succinctly?
> >>
> >> t.
> >>
> >> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> >>
> >>> Anyone else have opinions on which of these two basic approaches
> they
> >>> prefer? Tom, any thoughts?
> >>>
> >>> David
> >>>
> >>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <>
> wrote:
> >>>> But consider again the macro definitions which would allow
> >>>>
> >>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998,
> 1.0);
> >>>>
> >>>> or
> >>>>
> >>>> DefineIntTable(data, 123, 456, 789);
> >>>>
> >>>> These pass the usefulness test with flying colors, are really easy
> to
> >>>> explain, and don't have any off-putting squiggles. They solve all
> the
> >>>> global/local technical difficulties I describe below, yet look
> comfortably
> >>>> familiar to the beginner's eye. The objection, I believe, is that
> they look
> >>>> like function calls, and function calls seem wrong floating in
> space at
> >>>> global scope. But those who raise this objection do so precisely
> because
> >>>> they are intimate with the language. I suspect beginners would
> hardly be
> >>>> fazed. And whatever minor confusions the syntax might present are
> surely
> >>>> easier to document away than, say,
> >>>>
> >>>>> int data[] PROGMEM = { 123, 456, 789 };
> >>>>> IntTable sample(data);
> >>>>
> >>>> My point is that I think the ability to define Flash-based table
> objects at
> >>>> any scope with a tight and reasonable syntax warrants
> reconsideration of the
> >>>> Definexxx() style macros, despite the similarity to function
> calls. Some
> >>>> concepts are compelling enough to suggest tiny stretches of the
> language
> >>>> boundaries. F() is one of those, and I think tables are too.
> >>>>
> >>>> Mikal
> >>
> >>
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
On Mar 29, 2011, at 7:55 PM, Mikal Hart wrote:
> Tom, would you find something like
>
> DefineIntTable(sample, { 123, 456, 789 } );
>
> less objectionable?
No, it'd be more objectionable to me. It introduces a new structure of punctuation that adds confusion without clarifying anything. It's almost as bad as my least favorite in Processing, Serial.list()[0]. Way too much packed in there. Which is also why we need a print function for IPAddresses, by the way.
>
> First, it seems harder to explain and conceptualize. What does all that
> (apparently superfluous) typing mean? If all I want is to make an integer
> table called "sample", why do I have to type 2 lines with "extra" stuff like
> "data" and "PROGMEM" (or whatever)?
Actually, more typing is usually easier to explain and conceptualize. Terseness is great for experienced programmers, but for beginners, and especially beginners who don't necessarily want to be programers, verboseness actually works better. You don't have to remember what things mean, you just read the word. And when the punctuation is simple and clearly defined, even better. Multiple brackets make things worse, and grammar forms that do different things but look the same are a disaster.
>
> And pulling back that curtain on these implementation details leads to new
> errors.
>
> For example, imagine building a sine table using the above as a reference.
> You know that sines are floats and not ints, so you change line 1 to
>
> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>
> So far so good, but now you also need to remember to change "IntTable" to
> "FloatTable" in line 2, and you also need to make sure that the "data" in
> parentheses changes to "sines" to match the array name.
That's not such a problem, because there's a parallelism to it. It makes sense that I build an intTable with ints and a floatTable with floats. I don't think it's always necessary to hide things to make them simple. You have to give people credit for intelligence, even when they lack knowledge. A clear grammar that they can figure out is better than a simple one that's harder to expand.
> And of course thekiller is that
> Serial.print(sines[x]);
>
> compiles but fails miserably and inexplicably.
That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
>
>
> To my mind, its bulk and inherent fragility sink the multiline syntax. But
> it's good to talk about.
I'm okay with a single line syntax if it's clearly different from other structures, and grammatically and syntatically straightforward, and reveals how it works through its structure. Dave already shot down some of the possibilities I'd consider, so I won't bother with them.
The two-line PROGMEM syntax isn't perfect, I'll agree. But I think it's better than any of the three options presented so far. I'm happy to see other options, though.
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
>> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>> And of course thekiller is that
>> Serial.print(sines[x]);
>>
>> compiles but fails miserably and inexplicably.
> That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
The compiler does not know where "sines" will be placed in memory; the
linker determines that. The compiler generates the executable code for
this...
Serial.print(sines[x]);
...but leaves a place-holder for the address of "sines". The linker
substitutes the place-holder for the actual address of "sines".
The compiler has absolutely no awareness of PROGMEM data^1 . It sees
"sines" as an ordinary array of floats. The code generated by the
compiler for the "print" reads the value from SRAM. The linker puts
"sines" in Flash and substitutes the place-holder for the address.
Basically, "sines" is stored in Flash but the code reads from SRAM.
^1 Which is why it is impossible to devise a more user friendly syntax
for PROGMEM data.
- Brian
On 30/03/2011, at 3:22 , David A. Mellis wrote:
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
One way to mitigate this would be by convention, something like:
IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
IntTable sample(sample_PROGMEM_reference);
Another possible defence of the latter format would be
typedef IntData struct { int value; }
That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
Enjoy,
Peter.
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
t.
On Mar 30, 2011, at 9:47 PM, Peter N Lewis wrote:
> On 30/03/2011, at 3:22 , David A. Mellis wrote:
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>>
>> Or (and again, we can use any names here):
>>
>> IntData data[] = { 123, 456, 789 };
>> IntTable sample(data);
>
> To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
>
> Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
>
> One way to mitigate this would be by convention, something like:
>
> IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
> IntTable sample(sample_PROGMEM_reference);
>
> Another possible defence of the latter format would be
>
> typedef IntData struct { int value; }
>
> That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
>
> If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
>
> Enjoy,
> Peter.
>
>
>
>>
>> Any preferences?
>>
>> It's apparently impossible to do any of these:
>>
>> IntTable sample = { 123, 456, 789 };
>> IntTable sample(123, 456, 789);
>> IntTable sample = IntTable(123, 456, 789);
>> IntTable sample = IntTableData(123, 456, 789);
>>
>> at least, not in way that works at global scope (outside of a
>> function), which seems like the most important place to be able to
>> define a lookup table.
>>
>> David
>>
>> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>>> I'm a little confused. can you explain the two approaches succinctly?
>>>
>>> t.
>>>
>>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>>
>>>> Anyone else have opinions on which of these two basic approaches they
>>>> prefer? Tom, any thoughts?
>>>>
>>>> David
>>>>
>>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>>> But consider again the macro definitions which would allow
>>>>>
>>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>>
>>>>> or
>>>>>
>>>>> DefineIntTable(data, 123, 456, 789);
>>>>>
>>>>> These pass the usefulness test with flying colors, are really easy to
>>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>>> global/local technical difficulties I describe below, yet look comfortably
>>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>>> like function calls, and function calls seem wrong floating in space at
>>>>> global scope. But those who raise this objection do so precisely because
>>>>> they are intimate with the language. I suspect beginners would hardly be
>>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>>> easier to document away than, say,
>>>>>
>>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>>> IntTable sample(data);
>>>>>
>>>>> My point is that I think the ability to define Flash-based table objects at
>>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>>> boundaries. F() is one of those, and I think tables are too.
>>>>>
>>>>> Mikal
>>>
>>>
>>
>> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
|
# 11

31-03-2011 02:01 PM
|
|
|
Anyone else have opinions on which of these two basic approaches they
prefer? Tom, any thoughts?
David
On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
> But consider again the macro definitions which would allow
>
> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>
> or
>
> DefineIntTable(data, 123, 456, 789);
>
> These pass the usefulness test with flying colors, are really easy to
> explain, and don't have any off-putting squiggles. They solve all the
> global/local technical difficulties I describe below, yet look comfortably
> familiar to the beginner's eye. The objection, I believe, is that they look
> like function calls, and function calls seem wrong floating in space at
> global scope. But those who raise this objection do so precisely because
> they are intimate with the language. I suspect beginners would hardly be
> fazed. And whatever minor confusions the syntax might present are surely
> easier to document away than, say,
>
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>
> My point is that I think the ability to define Flash-based table objects at
> any scope with a tight and reasonable syntax warrants reconsideration of the
> Definexxx() style macros, despite the similarity to function calls. Some
> concepts are compelling enough to suggest tiny stretches of the language
> boundaries. F() is one of those, and I think tables are too.
>
> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I'm a little confused. can you explain the two approaches succinctly?
t.
On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> Anyone else have opinions on which of these two basic approaches they
> prefer? Tom, any thoughts?
>
> David
>
> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>> But consider again the macro definitions which would allow
>>
>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>
>> or
>>
>> DefineIntTable(data, 123, 456, 789);
>>
>> These pass the usefulness test with flying colors, are really easy to
>> explain, and don't have any off-putting squiggles. They solve all the
>> global/local technical difficulties I describe below, yet look comfortably
>> familiar to the beginner's eye. The objection, I believe, is that they look
>> like function calls, and function calls seem wrong floating in space at
>> global scope. But those who raise this objection do so precisely because
>> they are intimate with the language. I suspect beginners would hardly be
>> fazed. And whatever minor confusions the syntax might present are surely
>> easier to document away than, say,
>>
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> My point is that I think the ability to define Flash-based table objects at
>> any scope with a tight and reasonable syntax warrants reconsideration of the
>> Definexxx() style macros, despite the similarity to function calls. Some
>> concepts are compelling enough to suggest tiny stretches of the language
>> boundaries. F() is one of those, and I think tables are too.
>>
>> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
They both do the same thing: create an object that allows you to
access data stored in program memory (flash) using the [] array access
syntax. The question is which syntax we prefer for doing so:
DefineIntTable(data, 123, 456, 789);
Or (and here we could replace "PROGMEM" with any other word):
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Or (and again, we can use any names here):
IntData data[] = { 123, 456, 789 };
IntTable sample(data);
Any preferences?
It's apparently impossible to do any of these:
IntTable sample = { 123, 456, 789 };
IntTable sample(123, 456, 789);
IntTable sample = IntTable(123, 456, 789);
IntTable sample = IntTableData(123, 456, 789);
at least, not in way that works at global scope (outside of a
function), which seems like the most important place to be able to
define a lookup table.
David
On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
> I'm a little confused. can you explain the two approaches succinctly?
>
> t.
>
> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>
>> Anyone else have opinions on which of these two basic approaches they
>> prefer? Tom, any thoughts?
>>
>> David
>>
>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>> But consider again the macro definitions which would allow
>>>
>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>
>>> or
>>>
>>> DefineIntTable(data, 123, 456, 789);
>>>
>>> These pass the usefulness test with flying colors, are really easy to
>>> explain, and don't have any off-putting squiggles. They solve all the
>>> global/local technical difficulties I describe below, yet look comfortably
>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>> like function calls, and function calls seem wrong floating in space at
>>> global scope. But those who raise this objection do so precisely because
>>> they are intimate with the language. I suspect beginners would hardly be
>>> fazed. And whatever minor confusions the syntax might present are surely
>>> easier to document away than, say,
>>>
>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>> IntTable sample(data);
>>>
>>> My point is that I think the ability to define Flash-based table objects at
>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>> Definexxx() style macros, despite the similarity to function calls. Some
>>> concepts are compelling enough to suggest tiny stretches of the language
>>> boundaries. F() is one of those, and I think tables are too.
>>>
>>> Mikal
>
>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
These are all baby steps toward std::vector. It might be worth taking some inspiration from that direction, one way or another.
= Mike
On Mar 29, 2011, at 12:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I don't like the first version because it's unclear that data is {123, 456, 789}. It seems like data is one more element in the intTable. It should be clear that data is not the same class of thing as the things which comprise it.
The nice thing about the PROGMEM keyword is that it makes it explicit that there is something special about this array. Even if I don't yet know what an intTable is, I know there is a difference between
int data[] PROGMEM = { 123, 456, 789 };
and
int data[] = { 123, 456, 789 };
So on the whole I guess that means I prefer:
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Presumably then when I want to acces the data, I do this:
int foo = sample[1];
Serial.print(foo, DEC);
On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Tom, would you find something like
DefineIntTable(sample, { 123, 456, 789 } );
less objectionable?
In my mind there are two problems with the multiline syntax.
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
First, it seems harder to explain and conceptualize. What does all that
(apparently superfluous) typing mean? If all I want is to make an integer
table called "sample", why do I have to type 2 lines with "extra" stuff like
"data" and "PROGMEM" (or whatever)?
And pulling back that curtain on these implementation details leads to new
errors.
For example, imagine building a sine table using the above as a reference.
You know that sines are floats and not ints, so you change line 1 to
float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
So far so good, but now you also need to remember to change "IntTable" to
"FloatTable" in line 2, and you also need to make sure that the "data" in
parentheses changes to "sines" to match the array name. And of course the
killer is that
Serial.print(sines[x]);
compiles but fails miserably and inexplicably.
To my mind, its bulk and inherent fragility sink the multiline syntax. But
it's good to talk about.
Mikal
> -----Original Message-----
> From: Tom Igoe [mailto:]
> Sent: Tuesday, March 29, 2011 2:58 PM
> To: David A. Mellis
> Cc: Mikal Hart; Arduino Developers
> Subject: Re: Syntax for PROGMEM Lookup Tables
>
> I don't like the first version because it's unclear that data is {123,
> 456, 789}. It seems like data is one more element in the intTable. It
> should be clear that data is not the same class of thing as the things
> which comprise it.
>
> The nice thing about the PROGMEM keyword is that it makes it explicit
> that there is something special about this array. Even if I don't yet
> know what an intTable is, I know there is a difference between
>
> int data[] PROGMEM = { 123, 456, 789 };
>
> and
>
> int data[] = { 123, 456, 789 };
>
> So on the whole I guess that means I prefer:
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Presumably then when I want to acces the data, I do this:
>
> int foo = sample[1];
> Serial.print(foo, DEC);
>
>
> On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
>
> > They both do the same thing: create an object that allows you to
> > access data stored in program memory (flash) using the [] array
> access
> > syntax. The question is which syntax we prefer for doing so:
> >
> > DefineIntTable(data, 123, 456, 789);
> >
> > Or (and here we could replace "PROGMEM" with any other word):
> >
> > int data[] PROGMEM = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Or (and again, we can use any names here):
> >
> > IntData data[] = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Any preferences?
> >
> > It's apparently impossible to do any of these:
> >
> > IntTable sample = { 123, 456, 789 };
> > IntTable sample(123, 456, 789);
> > IntTable sample = IntTable(123, 456, 789);
> > IntTable sample = IntTableData(123, 456, 789);
> >
> > at least, not in way that works at global scope (outside of a
> > function), which seems like the most important place to be able to
> > define a lookup table.
> >
> > David
> >
> > On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <>
> wrote:
> >> I'm a little confused. can you explain the two approaches
> succinctly?
> >>
> >> t.
> >>
> >> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> >>
> >>> Anyone else have opinions on which of these two basic approaches
> they
> >>> prefer? Tom, any thoughts?
> >>>
> >>> David
> >>>
> >>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <>
> wrote:
> >>>> But consider again the macro definitions which would allow
> >>>>
> >>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998,
> 1.0);
> >>>>
> >>>> or
> >>>>
> >>>> DefineIntTable(data, 123, 456, 789);
> >>>>
> >>>> These pass the usefulness test with flying colors, are really easy
> to
> >>>> explain, and don't have any off-putting squiggles. They solve all
> the
> >>>> global/local technical difficulties I describe below, yet look
> comfortably
> >>>> familiar to the beginner's eye. The objection, I believe, is that
> they look
> >>>> like function calls, and function calls seem wrong floating in
> space at
> >>>> global scope. But those who raise this objection do so precisely
> because
> >>>> they are intimate with the language. I suspect beginners would
> hardly be
> >>>> fazed. And whatever minor confusions the syntax might present are
> surely
> >>>> easier to document away than, say,
> >>>>
> >>>>> int data[] PROGMEM = { 123, 456, 789 };
> >>>>> IntTable sample(data);
> >>>>
> >>>> My point is that I think the ability to define Flash-based table
> objects at
> >>>> any scope with a tight and reasonable syntax warrants
> reconsideration of the
> >>>> Definexxx() style macros, despite the similarity to function
> calls. Some
> >>>> concepts are compelling enough to suggest tiny stretches of the
> language
> >>>> boundaries. F() is one of those, and I think tables are too.
> >>>>
> >>>> Mikal
> >>
> >>
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
On Mar 29, 2011, at 7:55 PM, Mikal Hart wrote:
> Tom, would you find something like
>
> DefineIntTable(sample, { 123, 456, 789 } );
>
> less objectionable?
No, it'd be more objectionable to me. It introduces a new structure of punctuation that adds confusion without clarifying anything. It's almost as bad as my least favorite in Processing, Serial.list()[0]. Way too much packed in there. Which is also why we need a print function for IPAddresses, by the way.
>
> First, it seems harder to explain and conceptualize. What does all that
> (apparently superfluous) typing mean? If all I want is to make an integer
> table called "sample", why do I have to type 2 lines with "extra" stuff like
> "data" and "PROGMEM" (or whatever)?
Actually, more typing is usually easier to explain and conceptualize. Terseness is great for experienced programmers, but for beginners, and especially beginners who don't necessarily want to be programers, verboseness actually works better. You don't have to remember what things mean, you just read the word. And when the punctuation is simple and clearly defined, even better. Multiple brackets make things worse, and grammar forms that do different things but look the same are a disaster.
>
> And pulling back that curtain on these implementation details leads to new
> errors.
>
> For example, imagine building a sine table using the above as a reference.
> You know that sines are floats and not ints, so you change line 1 to
>
> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>
> So far so good, but now you also need to remember to change "IntTable" to
> "FloatTable" in line 2, and you also need to make sure that the "data" in
> parentheses changes to "sines" to match the array name.
That's not such a problem, because there's a parallelism to it. It makes sense that I build an intTable with ints and a floatTable with floats. I don't think it's always necessary to hide things to make them simple. You have to give people credit for intelligence, even when they lack knowledge. A clear grammar that they can figure out is better than a simple one that's harder to expand.
> And of course thekiller is that
> Serial.print(sines[x]);
>
> compiles but fails miserably and inexplicably.
That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
>
>
> To my mind, its bulk and inherent fragility sink the multiline syntax. But
> it's good to talk about.
I'm okay with a single line syntax if it's clearly different from other structures, and grammatically and syntatically straightforward, and reveals how it works through its structure. Dave already shot down some of the possibilities I'd consider, so I won't bother with them.
The two-line PROGMEM syntax isn't perfect, I'll agree. But I think it's better than any of the three options presented so far. I'm happy to see other options, though.
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
>> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>> And of course thekiller is that
>> Serial.print(sines[x]);
>>
>> compiles but fails miserably and inexplicably.
> That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
The compiler does not know where "sines" will be placed in memory; the
linker determines that. The compiler generates the executable code for
this...
Serial.print(sines[x]);
...but leaves a place-holder for the address of "sines". The linker
substitutes the place-holder for the actual address of "sines".
The compiler has absolutely no awareness of PROGMEM data^1 . It sees
"sines" as an ordinary array of floats. The code generated by the
compiler for the "print" reads the value from SRAM. The linker puts
"sines" in Flash and substitutes the place-holder for the address.
Basically, "sines" is stored in Flash but the code reads from SRAM.
^1 Which is why it is impossible to devise a more user friendly syntax
for PROGMEM data.
- Brian
On 30/03/2011, at 3:22 , David A. Mellis wrote:
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
One way to mitigate this would be by convention, something like:
IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
IntTable sample(sample_PROGMEM_reference);
Another possible defence of the latter format would be
typedef IntData struct { int value; }
That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
Enjoy,
Peter.
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
t.
On Mar 30, 2011, at 9:47 PM, Peter N Lewis wrote:
> On 30/03/2011, at 3:22 , David A. Mellis wrote:
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>>
>> Or (and again, we can use any names here):
>>
>> IntData data[] = { 123, 456, 789 };
>> IntTable sample(data);
>
> To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
>
> Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
>
> One way to mitigate this would be by convention, something like:
>
> IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
> IntTable sample(sample_PROGMEM_reference);
>
> Another possible defence of the latter format would be
>
> typedef IntData struct { int value; }
>
> That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
>
> If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
>
> Enjoy,
> Peter.
>
>
>
>>
>> Any preferences?
>>
>> It's apparently impossible to do any of these:
>>
>> IntTable sample = { 123, 456, 789 };
>> IntTable sample(123, 456, 789);
>> IntTable sample = IntTable(123, 456, 789);
>> IntTable sample = IntTableData(123, 456, 789);
>>
>> at least, not in way that works at global scope (outside of a
>> function), which seems like the most important place to be able to
>> define a lookup table.
>>
>> David
>>
>> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>>> I'm a little confused. can you explain the two approaches succinctly?
>>>
>>> t.
>>>
>>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>>
>>>> Anyone else have opinions on which of these two basic approaches they
>>>> prefer? Tom, any thoughts?
>>>>
>>>> David
>>>>
>>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>>> But consider again the macro definitions which would allow
>>>>>
>>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>>
>>>>> or
>>>>>
>>>>> DefineIntTable(data, 123, 456, 789);
>>>>>
>>>>> These pass the usefulness test with flying colors, are really easy to
>>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>>> global/local technical difficulties I describe below, yet look comfortably
>>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>>> like function calls, and function calls seem wrong floating in space at
>>>>> global scope. But those who raise this objection do so precisely because
>>>>> they are intimate with the language. I suspect beginners would hardly be
>>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>>> easier to document away than, say,
>>>>>
>>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>>> IntTable sample(data);
>>>>>
>>>>> My point is that I think the ability to define Flash-based table objects at
>>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>>> boundaries. F() is one of those, and I think tables are too.
>>>>>
>>>>> Mikal
>>>
>>>
>>
>> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
On Thu, Mar 31, 2011 at 7:36 AM, Tom Igoe <> wrote:
> Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
An interactive application with lots of menus/prompts is where I was
forced to learn about PROGMEM. Web applications are pretty verbose,
too, with lots of fixed strings.
I could see a novice hitting either one of those scenarios.
-Jason
kg4wsv
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
|
# 12

31-03-2011 02:22 PM
|
|
|
Anyone else have opinions on which of these two basic approaches they
prefer? Tom, any thoughts?
David
On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
> But consider again the macro definitions which would allow
>
> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>
> or
>
> DefineIntTable(data, 123, 456, 789);
>
> These pass the usefulness test with flying colors, are really easy to
> explain, and don't have any off-putting squiggles. They solve all the
> global/local technical difficulties I describe below, yet look comfortably
> familiar to the beginner's eye. The objection, I believe, is that they look
> like function calls, and function calls seem wrong floating in space at
> global scope. But those who raise this objection do so precisely because
> they are intimate with the language. I suspect beginners would hardly be
> fazed. And whatever minor confusions the syntax might present are surely
> easier to document away than, say,
>
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>
> My point is that I think the ability to define Flash-based table objects at
> any scope with a tight and reasonable syntax warrants reconsideration of the
> Definexxx() style macros, despite the similarity to function calls. Some
> concepts are compelling enough to suggest tiny stretches of the language
> boundaries. F() is one of those, and I think tables are too.
>
> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I'm a little confused. can you explain the two approaches succinctly?
t.
On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> Anyone else have opinions on which of these two basic approaches they
> prefer? Tom, any thoughts?
>
> David
>
> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>> But consider again the macro definitions which would allow
>>
>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>
>> or
>>
>> DefineIntTable(data, 123, 456, 789);
>>
>> These pass the usefulness test with flying colors, are really easy to
>> explain, and don't have any off-putting squiggles. They solve all the
>> global/local technical difficulties I describe below, yet look comfortably
>> familiar to the beginner's eye. The objection, I believe, is that they look
>> like function calls, and function calls seem wrong floating in space at
>> global scope. But those who raise this objection do so precisely because
>> they are intimate with the language. I suspect beginners would hardly be
>> fazed. And whatever minor confusions the syntax might present are surely
>> easier to document away than, say,
>>
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> My point is that I think the ability to define Flash-based table objects at
>> any scope with a tight and reasonable syntax warrants reconsideration of the
>> Definexxx() style macros, despite the similarity to function calls. Some
>> concepts are compelling enough to suggest tiny stretches of the language
>> boundaries. F() is one of those, and I think tables are too.
>>
>> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
They both do the same thing: create an object that allows you to
access data stored in program memory (flash) using the [] array access
syntax. The question is which syntax we prefer for doing so:
DefineIntTable(data, 123, 456, 789);
Or (and here we could replace "PROGMEM" with any other word):
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Or (and again, we can use any names here):
IntData data[] = { 123, 456, 789 };
IntTable sample(data);
Any preferences?
It's apparently impossible to do any of these:
IntTable sample = { 123, 456, 789 };
IntTable sample(123, 456, 789);
IntTable sample = IntTable(123, 456, 789);
IntTable sample = IntTableData(123, 456, 789);
at least, not in way that works at global scope (outside of a
function), which seems like the most important place to be able to
define a lookup table.
David
On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
> I'm a little confused. can you explain the two approaches succinctly?
>
> t.
>
> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>
>> Anyone else have opinions on which of these two basic approaches they
>> prefer? Tom, any thoughts?
>>
>> David
>>
>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>> But consider again the macro definitions which would allow
>>>
>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>
>>> or
>>>
>>> DefineIntTable(data, 123, 456, 789);
>>>
>>> These pass the usefulness test with flying colors, are really easy to
>>> explain, and don't have any off-putting squiggles. They solve all the
>>> global/local technical difficulties I describe below, yet look comfortably
>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>> like function calls, and function calls seem wrong floating in space at
>>> global scope. But those who raise this objection do so precisely because
>>> they are intimate with the language. I suspect beginners would hardly be
>>> fazed. And whatever minor confusions the syntax might present are surely
>>> easier to document away than, say,
>>>
>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>> IntTable sample(data);
>>>
>>> My point is that I think the ability to define Flash-based table objects at
>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>> Definexxx() style macros, despite the similarity to function calls. Some
>>> concepts are compelling enough to suggest tiny stretches of the language
>>> boundaries. F() is one of those, and I think tables are too.
>>>
>>> Mikal
>
>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
These are all baby steps toward std::vector. It might be worth taking some inspiration from that direction, one way or another.
= Mike
On Mar 29, 2011, at 12:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I don't like the first version because it's unclear that data is {123, 456, 789}. It seems like data is one more element in the intTable. It should be clear that data is not the same class of thing as the things which comprise it.
The nice thing about the PROGMEM keyword is that it makes it explicit that there is something special about this array. Even if I don't yet know what an intTable is, I know there is a difference between
int data[] PROGMEM = { 123, 456, 789 };
and
int data[] = { 123, 456, 789 };
So on the whole I guess that means I prefer:
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Presumably then when I want to acces the data, I do this:
int foo = sample[1];
Serial.print(foo, DEC);
On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Tom, would you find something like
DefineIntTable(sample, { 123, 456, 789 } );
less objectionable?
In my mind there are two problems with the multiline syntax.
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
First, it seems harder to explain and conceptualize. What does all that
(apparently superfluous) typing mean? If all I want is to make an integer
table called "sample", why do I have to type 2 lines with "extra" stuff like
"data" and "PROGMEM" (or whatever)?
And pulling back that curtain on these implementation details leads to new
errors.
For example, imagine building a sine table using the above as a reference.
You know that sines are floats and not ints, so you change line 1 to
float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
So far so good, but now you also need to remember to change "IntTable" to
"FloatTable" in line 2, and you also need to make sure that the "data" in
parentheses changes to "sines" to match the array name. And of course the
killer is that
Serial.print(sines[x]);
compiles but fails miserably and inexplicably.
To my mind, its bulk and inherent fragility sink the multiline syntax. But
it's good to talk about.
Mikal
> -----Original Message-----
> From: Tom Igoe [mailto:]
> Sent: Tuesday, March 29, 2011 2:58 PM
> To: David A. Mellis
> Cc: Mikal Hart; Arduino Developers
> Subject: Re: Syntax for PROGMEM Lookup Tables
>
> I don't like the first version because it's unclear that data is {123,
> 456, 789}. It seems like data is one more element in the intTable. It
> should be clear that data is not the same class of thing as the things
> which comprise it.
>
> The nice thing about the PROGMEM keyword is that it makes it explicit
> that there is something special about this array. Even if I don't yet
> know what an intTable is, I know there is a difference between
>
> int data[] PROGMEM = { 123, 456, 789 };
>
> and
>
> int data[] = { 123, 456, 789 };
>
> So on the whole I guess that means I prefer:
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Presumably then when I want to acces the data, I do this:
>
> int foo = sample[1];
> Serial.print(foo, DEC);
>
>
> On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
>
> > They both do the same thing: create an object that allows you to
> > access data stored in program memory (flash) using the [] array
> access
> > syntax. The question is which syntax we prefer for doing so:
> >
> > DefineIntTable(data, 123, 456, 789);
> >
> > Or (and here we could replace "PROGMEM" with any other word):
> >
> > int data[] PROGMEM = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Or (and again, we can use any names here):
> >
> > IntData data[] = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Any preferences?
> >
> > It's apparently impossible to do any of these:
> >
> > IntTable sample = { 123, 456, 789 };
> > IntTable sample(123, 456, 789);
> > IntTable sample = IntTable(123, 456, 789);
> > IntTable sample = IntTableData(123, 456, 789);
> >
> > at least, not in way that works at global scope (outside of a
> > function), which seems like the most important place to be able to
> > define a lookup table.
> >
> > David
> >
> > On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <>
> wrote:
> >> I'm a little confused. can you explain the two approaches
> succinctly?
> >>
> >> t.
> >>
> >> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> >>
> >>> Anyone else have opinions on which of these two basic approaches
> they
> >>> prefer? Tom, any thoughts?
> >>>
> >>> David
> >>>
> >>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <>
> wrote:
> >>>> But consider again the macro definitions which would allow
> >>>>
> >>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998,
> 1.0);
> >>>>
> >>>> or
> >>>>
> >>>> DefineIntTable(data, 123, 456, 789);
> >>>>
> >>>> These pass the usefulness test with flying colors, are really easy
> to
> >>>> explain, and don't have any off-putting squiggles. They solve all
> the
> >>>> global/local technical difficulties I describe below, yet look
> comfortably
> >>>> familiar to the beginner's eye. The objection, I believe, is that
> they look
> >>>> like function calls, and function calls seem wrong floating in
> space at
> >>>> global scope. But those who raise this objection do so precisely
> because
> >>>> they are intimate with the language. I suspect beginners would
> hardly be
> >>>> fazed. And whatever minor confusions the syntax might present are
> surely
> >>>> easier to document away than, say,
> >>>>
> >>>>> int data[] PROGMEM = { 123, 456, 789 };
> >>>>> IntTable sample(data);
> >>>>
> >>>> My point is that I think the ability to define Flash-based table
> objects at
> >>>> any scope with a tight and reasonable syntax warrants
> reconsideration of the
> >>>> Definexxx() style macros, despite the similarity to function
> calls. Some
> >>>> concepts are compelling enough to suggest tiny stretches of the
> language
> >>>> boundaries. F() is one of those, and I think tables are too.
> >>>>
> >>>> Mikal
> >>
> >>
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
On Mar 29, 2011, at 7:55 PM, Mikal Hart wrote:
> Tom, would you find something like
>
> DefineIntTable(sample, { 123, 456, 789 } );
>
> less objectionable?
No, it'd be more objectionable to me. It introduces a new structure of punctuation that adds confusion without clarifying anything. It's almost as bad as my least favorite in Processing, Serial.list()[0]. Way too much packed in there. Which is also why we need a print function for IPAddresses, by the way.
>
> First, it seems harder to explain and conceptualize. What does all that
> (apparently superfluous) typing mean? If all I want is to make an integer
> table called "sample", why do I have to type 2 lines with "extra" stuff like
> "data" and "PROGMEM" (or whatever)?
Actually, more typing is usually easier to explain and conceptualize. Terseness is great for experienced programmers, but for beginners, and especially beginners who don't necessarily want to be programers, verboseness actually works better. You don't have to remember what things mean, you just read the word. And when the punctuation is simple and clearly defined, even better. Multiple brackets make things worse, and grammar forms that do different things but look the same are a disaster.
>
> And pulling back that curtain on these implementation details leads to new
> errors.
>
> For example, imagine building a sine table using the above as a reference.
> You know that sines are floats and not ints, so you change line 1 to
>
> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>
> So far so good, but now you also need to remember to change "IntTable" to
> "FloatTable" in line 2, and you also need to make sure that the "data" in
> parentheses changes to "sines" to match the array name.
That's not such a problem, because there's a parallelism to it. It makes sense that I build an intTable with ints and a floatTable with floats. I don't think it's always necessary to hide things to make them simple. You have to give people credit for intelligence, even when they lack knowledge. A clear grammar that they can figure out is better than a simple one that's harder to expand.
> And of course thekiller is that
> Serial.print(sines[x]);
>
> compiles but fails miserably and inexplicably.
That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
>
>
> To my mind, its bulk and inherent fragility sink the multiline syntax. But
> it's good to talk about.
I'm okay with a single line syntax if it's clearly different from other structures, and grammatically and syntatically straightforward, and reveals how it works through its structure. Dave already shot down some of the possibilities I'd consider, so I won't bother with them.
The two-line PROGMEM syntax isn't perfect, I'll agree. But I think it's better than any of the three options presented so far. I'm happy to see other options, though.
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
>> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>> And of course thekiller is that
>> Serial.print(sines[x]);
>>
>> compiles but fails miserably and inexplicably.
> That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
The compiler does not know where "sines" will be placed in memory; the
linker determines that. The compiler generates the executable code for
this...
Serial.print(sines[x]);
...but leaves a place-holder for the address of "sines". The linker
substitutes the place-holder for the actual address of "sines".
The compiler has absolutely no awareness of PROGMEM data^1 . It sees
"sines" as an ordinary array of floats. The code generated by the
compiler for the "print" reads the value from SRAM. The linker puts
"sines" in Flash and substitutes the place-holder for the address.
Basically, "sines" is stored in Flash but the code reads from SRAM.
^1 Which is why it is impossible to devise a more user friendly syntax
for PROGMEM data.
- Brian
On 30/03/2011, at 3:22 , David A. Mellis wrote:
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
One way to mitigate this would be by convention, something like:
IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
IntTable sample(sample_PROGMEM_reference);
Another possible defence of the latter format would be
typedef IntData struct { int value; }
That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
Enjoy,
Peter.
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
t.
On Mar 30, 2011, at 9:47 PM, Peter N Lewis wrote:
> On 30/03/2011, at 3:22 , David A. Mellis wrote:
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>>
>> Or (and again, we can use any names here):
>>
>> IntData data[] = { 123, 456, 789 };
>> IntTable sample(data);
>
> To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
>
> Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
>
> One way to mitigate this would be by convention, something like:
>
> IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
> IntTable sample(sample_PROGMEM_reference);
>
> Another possible defence of the latter format would be
>
> typedef IntData struct { int value; }
>
> That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
>
> If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
>
> Enjoy,
> Peter.
>
>
>
>>
>> Any preferences?
>>
>> It's apparently impossible to do any of these:
>>
>> IntTable sample = { 123, 456, 789 };
>> IntTable sample(123, 456, 789);
>> IntTable sample = IntTable(123, 456, 789);
>> IntTable sample = IntTableData(123, 456, 789);
>>
>> at least, not in way that works at global scope (outside of a
>> function), which seems like the most important place to be able to
>> define a lookup table.
>>
>> David
>>
>> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>>> I'm a little confused. can you explain the two approaches succinctly?
>>>
>>> t.
>>>
>>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>>
>>>> Anyone else have opinions on which of these two basic approaches they
>>>> prefer? Tom, any thoughts?
>>>>
>>>> David
>>>>
>>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>>> But consider again the macro definitions which would allow
>>>>>
>>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>>
>>>>> or
>>>>>
>>>>> DefineIntTable(data, 123, 456, 789);
>>>>>
>>>>> These pass the usefulness test with flying colors, are really easy to
>>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>>> global/local technical difficulties I describe below, yet look comfortably
>>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>>> like function calls, and function calls seem wrong floating in space at
>>>>> global scope. But those who raise this objection do so precisely because
>>>>> they are intimate with the language. I suspect beginners would hardly be
>>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>>> easier to document away than, say,
>>>>>
>>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>>> IntTable sample(data);
>>>>>
>>>>> My point is that I think the ability to define Flash-based table objects at
>>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>>> boundaries. F() is one of those, and I think tables are too.
>>>>>
>>>>> Mikal
>>>
>>>
>>
>> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
On Thu, Mar 31, 2011 at 7:36 AM, Tom Igoe <> wrote:
> Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
An interactive application with lots of menus/prompts is where I was
forced to learn about PROGMEM. Web applications are pretty verbose,
too, with lots of fixed strings.
I could see a novice hitting either one of those scenarios.
-Jason
kg4wsv
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
In can be useful for things like audio data (either a full sample or a
wave-form shape) or for images or a font to be displayed on an LED
matrix, etc.
I agree, it's not a huge priority, but it's probably useful enough to
include. In part, this is why I like the two-line solution, because
the first line is the existing notation and the second just wraps it
in a way that makes it accessible using a standard syntax. Otherwise,
to get data from a PROGMEM array, you need to do something like
prog_read_byte(table + n) instead of table[n].
David
On Thu, Mar 31, 2011 at 8:36 AM, Tom Igoe <> wrote:
> Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
> t.
>
> On Mar 30, 2011, at 9:47 PM, Peter N Lewis wrote:
>
>> On 30/03/2011, at 3:22 , David A. Mellis wrote:
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>>
>>> Or (and again, we can use any names here):
>>>
>>> IntData data[] = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
>>
>> Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
>>
>> One way to mitigate this would be by convention, something like:
>>
>> IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
>> IntTable sample(sample_PROGMEM_reference);
>>
>> Another possible defence of the latter format would be
>>
>> typedef IntData struct { int value; }
>>
>> That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
>>
>> If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
>>
>> Enjoy,
>> Peter.
>>
>>
>>
>>>
>>> Any preferences?
>>>
>>> It's apparently impossible to do any of these:
>>>
>>> IntTable sample = { 123, 456, 789 };
>>> IntTable sample(123, 456, 789);
>>> IntTable sample = IntTable(123, 456, 789);
>>> IntTable sample = IntTableData(123, 456, 789);
>>>
>>> at least, not in way that works at global scope (outside of a
>>> function), which seems like the most important place to be able to
>>> define a lookup table.
>>>
>>> David
>>>
>>> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>>>> I'm a little confused. can you explain the two approaches succinctly?
>>>>
>>>> t.
>>>>
>>>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>>>
>>>>> Anyone else have opinions on which of these two basic approaches they
>>>>> prefer? Tom, any thoughts?
>>>>>
>>>>> David
>>>>>
>>>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>>>> But consider again the macro definitions which would allow
>>>>>>
>>>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>>>
>>>>>> or
>>>>>>
>>>>>> DefineIntTable(data, 123, 456, 789);
>>>>>>
>>>>>> These pass the usefulness test with flying colors, are really easy to
>>>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>>>> global/local technical difficulties I describe below, yet look comfortably
>>>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>>>> like function calls, and function calls seem wrong floating in space at
>>>>>> global scope. But those who raise this objection do so precisely because
>>>>>> they are intimate with the language. I suspect beginners would hardly be
>>>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>>>> easier to document away than, say,
>>>>>>
>>>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>>>> IntTable sample(data);
>>>>>>
>>>>>> My point is that I think the ability to define Flash-based table objects at
>>>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>>>> boundaries. F() is one of those, and I think tables are too.
>>>>>>
>>>>>> Mikal
>>>>
>>>>
>>>
>>> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
|
# 13

31-03-2011 05:58 PM
|
|
|
Anyone else have opinions on which of these two basic approaches they
prefer? Tom, any thoughts?
David
On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
> But consider again the macro definitions which would allow
>
> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>
> or
>
> DefineIntTable(data, 123, 456, 789);
>
> These pass the usefulness test with flying colors, are really easy to
> explain, and don't have any off-putting squiggles. They solve all the
> global/local technical difficulties I describe below, yet look comfortably
> familiar to the beginner's eye. The objection, I believe, is that they look
> like function calls, and function calls seem wrong floating in space at
> global scope. But those who raise this objection do so precisely because
> they are intimate with the language. I suspect beginners would hardly be
> fazed. And whatever minor confusions the syntax might present are surely
> easier to document away than, say,
>
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>
> My point is that I think the ability to define Flash-based table objects at
> any scope with a tight and reasonable syntax warrants reconsideration of the
> Definexxx() style macros, despite the similarity to function calls. Some
> concepts are compelling enough to suggest tiny stretches of the language
> boundaries. F() is one of those, and I think tables are too.
>
> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I'm a little confused. can you explain the two approaches succinctly?
t.
On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> Anyone else have opinions on which of these two basic approaches they
> prefer? Tom, any thoughts?
>
> David
>
> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>> But consider again the macro definitions which would allow
>>
>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>
>> or
>>
>> DefineIntTable(data, 123, 456, 789);
>>
>> These pass the usefulness test with flying colors, are really easy to
>> explain, and don't have any off-putting squiggles. They solve all the
>> global/local technical difficulties I describe below, yet look comfortably
>> familiar to the beginner's eye. The objection, I believe, is that they look
>> like function calls, and function calls seem wrong floating in space at
>> global scope. But those who raise this objection do so precisely because
>> they are intimate with the language. I suspect beginners would hardly be
>> fazed. And whatever minor confusions the syntax might present are surely
>> easier to document away than, say,
>>
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> My point is that I think the ability to define Flash-based table objects at
>> any scope with a tight and reasonable syntax warrants reconsideration of the
>> Definexxx() style macros, despite the similarity to function calls. Some
>> concepts are compelling enough to suggest tiny stretches of the language
>> boundaries. F() is one of those, and I think tables are too.
>>
>> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
They both do the same thing: create an object that allows you to
access data stored in program memory (flash) using the [] array access
syntax. The question is which syntax we prefer for doing so:
DefineIntTable(data, 123, 456, 789);
Or (and here we could replace "PROGMEM" with any other word):
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Or (and again, we can use any names here):
IntData data[] = { 123, 456, 789 };
IntTable sample(data);
Any preferences?
It's apparently impossible to do any of these:
IntTable sample = { 123, 456, 789 };
IntTable sample(123, 456, 789);
IntTable sample = IntTable(123, 456, 789);
IntTable sample = IntTableData(123, 456, 789);
at least, not in way that works at global scope (outside of a
function), which seems like the most important place to be able to
define a lookup table.
David
On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
> I'm a little confused. can you explain the two approaches succinctly?
>
> t.
>
> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>
>> Anyone else have opinions on which of these two basic approaches they
>> prefer? Tom, any thoughts?
>>
>> David
>>
>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>> But consider again the macro definitions which would allow
>>>
>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>
>>> or
>>>
>>> DefineIntTable(data, 123, 456, 789);
>>>
>>> These pass the usefulness test with flying colors, are really easy to
>>> explain, and don't have any off-putting squiggles. They solve all the
>>> global/local technical difficulties I describe below, yet look comfortably
>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>> like function calls, and function calls seem wrong floating in space at
>>> global scope. But those who raise this objection do so precisely because
>>> they are intimate with the language. I suspect beginners would hardly be
>>> fazed. And whatever minor confusions the syntax might present are surely
>>> easier to document away than, say,
>>>
>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>> IntTable sample(data);
>>>
>>> My point is that I think the ability to define Flash-based table objects at
>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>> Definexxx() style macros, despite the similarity to function calls. Some
>>> concepts are compelling enough to suggest tiny stretches of the language
>>> boundaries. F() is one of those, and I think tables are too.
>>>
>>> Mikal
>
>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
These are all baby steps toward std::vector. It might be worth taking some inspiration from that direction, one way or another.
= Mike
On Mar 29, 2011, at 12:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I don't like the first version because it's unclear that data is {123, 456, 789}. It seems like data is one more element in the intTable. It should be clear that data is not the same class of thing as the things which comprise it.
The nice thing about the PROGMEM keyword is that it makes it explicit that there is something special about this array. Even if I don't yet know what an intTable is, I know there is a difference between
int data[] PROGMEM = { 123, 456, 789 };
and
int data[] = { 123, 456, 789 };
So on the whole I guess that means I prefer:
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Presumably then when I want to acces the data, I do this:
int foo = sample[1];
Serial.print(foo, DEC);
On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Tom, would you find something like
DefineIntTable(sample, { 123, 456, 789 } );
less objectionable?
In my mind there are two problems with the multiline syntax.
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
First, it seems harder to explain and conceptualize. What does all that
(apparently superfluous) typing mean? If all I want is to make an integer
table called "sample", why do I have to type 2 lines with "extra" stuff like
"data" and "PROGMEM" (or whatever)?
And pulling back that curtain on these implementation details leads to new
errors.
For example, imagine building a sine table using the above as a reference.
You know that sines are floats and not ints, so you change line 1 to
float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
So far so good, but now you also need to remember to change "IntTable" to
"FloatTable" in line 2, and you also need to make sure that the "data" in
parentheses changes to "sines" to match the array name. And of course the
killer is that
Serial.print(sines[x]);
compiles but fails miserably and inexplicably.
To my mind, its bulk and inherent fragility sink the multiline syntax. But
it's good to talk about.
Mikal
> -----Original Message-----
> From: Tom Igoe [mailto:]
> Sent: Tuesday, March 29, 2011 2:58 PM
> To: David A. Mellis
> Cc: Mikal Hart; Arduino Developers
> Subject: Re: Syntax for PROGMEM Lookup Tables
>
> I don't like the first version because it's unclear that data is {123,
> 456, 789}. It seems like data is one more element in the intTable. It
> should be clear that data is not the same class of thing as the things
> which comprise it.
>
> The nice thing about the PROGMEM keyword is that it makes it explicit
> that there is something special about this array. Even if I don't yet
> know what an intTable is, I know there is a difference between
>
> int data[] PROGMEM = { 123, 456, 789 };
>
> and
>
> int data[] = { 123, 456, 789 };
>
> So on the whole I guess that means I prefer:
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Presumably then when I want to acces the data, I do this:
>
> int foo = sample[1];
> Serial.print(foo, DEC);
>
>
> On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
>
> > They both do the same thing: create an object that allows you to
> > access data stored in program memory (flash) using the [] array
> access
> > syntax. The question is which syntax we prefer for doing so:
> >
> > DefineIntTable(data, 123, 456, 789);
> >
> > Or (and here we could replace "PROGMEM" with any other word):
> >
> > int data[] PROGMEM = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Or (and again, we can use any names here):
> >
> > IntData data[] = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Any preferences?
> >
> > It's apparently impossible to do any of these:
> >
> > IntTable sample = { 123, 456, 789 };
> > IntTable sample(123, 456, 789);
> > IntTable sample = IntTable(123, 456, 789);
> > IntTable sample = IntTableData(123, 456, 789);
> >
> > at least, not in way that works at global scope (outside of a
> > function), which seems like the most important place to be able to
> > define a lookup table.
> >
> > David
> >
> > On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <>
> wrote:
> >> I'm a little confused. can you explain the two approaches
> succinctly?
> >>
> >> t.
> >>
> >> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> >>
> >>> Anyone else have opinions on which of these two basic approaches
> they
> >>> prefer? Tom, any thoughts?
> >>>
> >>> David
> >>>
> >>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <>
> wrote:
> >>>> But consider again the macro definitions which would allow
> >>>>
> >>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998,
> 1.0);
> >>>>
> >>>> or
> >>>>
> >>>> DefineIntTable(data, 123, 456, 789);
> >>>>
> >>>> These pass the usefulness test with flying colors, are really easy
> to
> >>>> explain, and don't have any off-putting squiggles. They solve all
> the
> >>>> global/local technical difficulties I describe below, yet look
> comfortably
> >>>> familiar to the beginner's eye. The objection, I believe, is that
> they look
> >>>> like function calls, and function calls seem wrong floating in
> space at
> >>>> global scope. But those who raise this objection do so precisely
> because
> >>>> they are intimate with the language. I suspect beginners would
> hardly be
> >>>> fazed. And whatever minor confusions the syntax might present are
> surely
> >>>> easier to document away than, say,
> >>>>
> >>>>> int data[] PROGMEM = { 123, 456, 789 };
> >>>>> IntTable sample(data);
> >>>>
> >>>> My point is that I think the ability to define Flash-based table
> objects at
> >>>> any scope with a tight and reasonable syntax warrants
> reconsideration of the
> >>>> Definexxx() style macros, despite the similarity to function
> calls. Some
> >>>> concepts are compelling enough to suggest tiny stretches of the
> language
> >>>> boundaries. F() is one of those, and I think tables are too.
> >>>>
> >>>> Mikal
> >>
> >>
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
On Mar 29, 2011, at 7:55 PM, Mikal Hart wrote:
> Tom, would you find something like
>
> DefineIntTable(sample, { 123, 456, 789 } );
>
> less objectionable?
No, it'd be more objectionable to me. It introduces a new structure of punctuation that adds confusion without clarifying anything. It's almost as bad as my least favorite in Processing, Serial.list()[0]. Way too much packed in there. Which is also why we need a print function for IPAddresses, by the way.
>
> First, it seems harder to explain and conceptualize. What does all that
> (apparently superfluous) typing mean? If all I want is to make an integer
> table called "sample", why do I have to type 2 lines with "extra" stuff like
> "data" and "PROGMEM" (or whatever)?
Actually, more typing is usually easier to explain and conceptualize. Terseness is great for experienced programmers, but for beginners, and especially beginners who don't necessarily want to be programers, verboseness actually works better. You don't have to remember what things mean, you just read the word. And when the punctuation is simple and clearly defined, even better. Multiple brackets make things worse, and grammar forms that do different things but look the same are a disaster.
>
> And pulling back that curtain on these implementation details leads to new
> errors.
>
> For example, imagine building a sine table using the above as a reference.
> You know that sines are floats and not ints, so you change line 1 to
>
> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>
> So far so good, but now you also need to remember to change "IntTable" to
> "FloatTable" in line 2, and you also need to make sure that the "data" in
> parentheses changes to "sines" to match the array name.
That's not such a problem, because there's a parallelism to it. It makes sense that I build an intTable with ints and a floatTable with floats. I don't think it's always necessary to hide things to make them simple. You have to give people credit for intelligence, even when they lack knowledge. A clear grammar that they can figure out is better than a simple one that's harder to expand.
> And of course thekiller is that
> Serial.print(sines[x]);
>
> compiles but fails miserably and inexplicably.
That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
>
>
> To my mind, its bulk and inherent fragility sink the multiline syntax. But
> it's good to talk about.
I'm okay with a single line syntax if it's clearly different from other structures, and grammatically and syntatically straightforward, and reveals how it works through its structure. Dave already shot down some of the possibilities I'd consider, so I won't bother with them.
The two-line PROGMEM syntax isn't perfect, I'll agree. But I think it's better than any of the three options presented so far. I'm happy to see other options, though.
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
>> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>> And of course thekiller is that
>> Serial.print(sines[x]);
>>
>> compiles but fails miserably and inexplicably.
> That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
The compiler does not know where "sines" will be placed in memory; the
linker determines that. The compiler generates the executable code for
this...
Serial.print(sines[x]);
...but leaves a place-holder for the address of "sines". The linker
substitutes the place-holder for the actual address of "sines".
The compiler has absolutely no awareness of PROGMEM data^1 . It sees
"sines" as an ordinary array of floats. The code generated by the
compiler for the "print" reads the value from SRAM. The linker puts
"sines" in Flash and substitutes the place-holder for the address.
Basically, "sines" is stored in Flash but the code reads from SRAM.
^1 Which is why it is impossible to devise a more user friendly syntax
for PROGMEM data.
- Brian
On 30/03/2011, at 3:22 , David A. Mellis wrote:
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
One way to mitigate this would be by convention, something like:
IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
IntTable sample(sample_PROGMEM_reference);
Another possible defence of the latter format would be
typedef IntData struct { int value; }
That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
Enjoy,
Peter.
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
t.
On Mar 30, 2011, at 9:47 PM, Peter N Lewis wrote:
> On 30/03/2011, at 3:22 , David A. Mellis wrote:
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>>
>> Or (and again, we can use any names here):
>>
>> IntData data[] = { 123, 456, 789 };
>> IntTable sample(data);
>
> To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
>
> Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
>
> One way to mitigate this would be by convention, something like:
>
> IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
> IntTable sample(sample_PROGMEM_reference);
>
> Another possible defence of the latter format would be
>
> typedef IntData struct { int value; }
>
> That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
>
> If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
>
> Enjoy,
> Peter.
>
>
>
>>
>> Any preferences?
>>
>> It's apparently impossible to do any of these:
>>
>> IntTable sample = { 123, 456, 789 };
>> IntTable sample(123, 456, 789);
>> IntTable sample = IntTable(123, 456, 789);
>> IntTable sample = IntTableData(123, 456, 789);
>>
>> at least, not in way that works at global scope (outside of a
>> function), which seems like the most important place to be able to
>> define a lookup table.
>>
>> David
>>
>> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>>> I'm a little confused. can you explain the two approaches succinctly?
>>>
>>> t.
>>>
>>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>>
>>>> Anyone else have opinions on which of these two basic approaches they
>>>> prefer? Tom, any thoughts?
>>>>
>>>> David
>>>>
>>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>>> But consider again the macro definitions which would allow
>>>>>
>>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>>
>>>>> or
>>>>>
>>>>> DefineIntTable(data, 123, 456, 789);
>>>>>
>>>>> These pass the usefulness test with flying colors, are really easy to
>>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>>> global/local technical difficulties I describe below, yet look comfortably
>>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>>> like function calls, and function calls seem wrong floating in space at
>>>>> global scope. But those who raise this objection do so precisely because
>>>>> they are intimate with the language. I suspect beginners would hardly be
>>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>>> easier to document away than, say,
>>>>>
>>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>>> IntTable sample(data);
>>>>>
>>>>> My point is that I think the ability to define Flash-based table objects at
>>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>>> boundaries. F() is one of those, and I think tables are too.
>>>>>
>>>>> Mikal
>>>
>>>
>>
>> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
On Thu, Mar 31, 2011 at 7:36 AM, Tom Igoe <> wrote:
> Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
An interactive application with lots of menus/prompts is where I was
forced to learn about PROGMEM. Web applications are pretty verbose,
too, with lots of fixed strings.
I could see a novice hitting either one of those scenarios.
-Jason
kg4wsv
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
In can be useful for things like audio data (either a full sample or a
wave-form shape) or for images or a font to be displayed on an LED
matrix, etc.
I agree, it's not a huge priority, but it's probably useful enough to
include. In part, this is why I like the two-line solution, because
the first line is the existing notation and the second just wraps it
in a way that makes it accessible using a standard syntax. Otherwise,
to get data from a PROGMEM array, you need to do something like
prog_read_byte(table + n) instead of table[n].
David
On Thu, Mar 31, 2011 at 8:36 AM, Tom Igoe <> wrote:
> Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
> t.
>
> On Mar 30, 2011, at 9:47 PM, Peter N Lewis wrote:
>
>> On 30/03/2011, at 3:22 , David A. Mellis wrote:
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>>
>>> Or (and again, we can use any names here):
>>>
>>> IntData data[] = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
>>
>> Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
>>
>> One way to mitigate this would be by convention, something like:
>>
>> IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
>> IntTable sample(sample_PROGMEM_reference);
>>
>> Another possible defence of the latter format would be
>>
>> typedef IntData struct { int value; }
>>
>> That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
>>
>> If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
>>
>> Enjoy,
>> Peter.
>>
>>
>>
>>>
>>> Any preferences?
>>>
>>> It's apparently impossible to do any of these:
>>>
>>> IntTable sample = { 123, 456, 789 };
>>> IntTable sample(123, 456, 789);
>>> IntTable sample = IntTable(123, 456, 789);
>>> IntTable sample = IntTableData(123, 456, 789);
>>>
>>> at least, not in way that works at global scope (outside of a
>>> function), which seems like the most important place to be able to
>>> define a lookup table.
>>>
>>> David
>>>
>>> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>>>> I'm a little confused. can you explain the two approaches succinctly?
>>>>
>>>> t.
>>>>
>>>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>>>
>>>>> Anyone else have opinions on which of these two basic approaches they
>>>>> prefer? Tom, any thoughts?
>>>>>
>>>>> David
>>>>>
>>>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>>>> But consider again the macro definitions which would allow
>>>>>>
>>>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>>>
>>>>>> or
>>>>>>
>>>>>> DefineIntTable(data, 123, 456, 789);
>>>>>>
>>>>>> These pass the usefulness test with flying colors, are really easy to
>>>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>>>> global/local technical difficulties I describe below, yet look comfortably
>>>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>>>> like function calls, and function calls seem wrong floating in space at
>>>>>> global scope. But those who raise this objection do so precisely because
>>>>>> they are intimate with the language. I suspect beginners would hardly be
>>>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>>>> easier to document away than, say,
>>>>>>
>>>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>>>> IntTable sample(data);
>>>>>>
>>>>>> My point is that I think the ability to define Flash-based table objects at
>>>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>>>> boundaries. F() is one of those, and I think tables are too.
>>>>>>
>>>>>> Mikal
>>>>
>>>>
>>>
>>> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
On Mar 31, 2011, at 9:01 AM, Jason KG4WSV wrote:
> On Thu, Mar 31, 2011 at 7:36 AM, Tom Igoe <> wrote:
>> Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
>
> An interactive application with lots of menus/prompts is where I was
> forced to learn about PROGMEM.
I can see the sense in that.
> Web applications are pretty verbose,
> too, with lots of fixed strings.
Web apps are not a good Arduino app, though. Putting a whole web app on an Arduino is like putting a 5'8" basketball player at center and telling the 7'2" guys not to help him. If you're on the net, use the net for what it's good for. Put your UI on the server, where you have good computational capability for UI, and have a back-end script contact the Arduino, and vice versa, or serve it from an SD card and let the client do the work.
>
> I could see a novice hitting either one of those scenarios.
I think by the time they hit the former, they'd be ready for the current 2-line PROGMEM syntax.
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
|
# 14

31-03-2011 05:59 PM
|
|
|
Anyone else have opinions on which of these two basic approaches they
prefer? Tom, any thoughts?
David
On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
> But consider again the macro definitions which would allow
>
> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>
> or
>
> DefineIntTable(data, 123, 456, 789);
>
> These pass the usefulness test with flying colors, are really easy to
> explain, and don't have any off-putting squiggles. They solve all the
> global/local technical difficulties I describe below, yet look comfortably
> familiar to the beginner's eye. The objection, I believe, is that they look
> like function calls, and function calls seem wrong floating in space at
> global scope. But those who raise this objection do so precisely because
> they are intimate with the language. I suspect beginners would hardly be
> fazed. And whatever minor confusions the syntax might present are surely
> easier to document away than, say,
>
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>
> My point is that I think the ability to define Flash-based table objects at
> any scope with a tight and reasonable syntax warrants reconsideration of the
> Definexxx() style macros, despite the similarity to function calls. Some
> concepts are compelling enough to suggest tiny stretches of the language
> boundaries. F() is one of those, and I think tables are too.
>
> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I'm a little confused. can you explain the two approaches succinctly?
t.
On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> Anyone else have opinions on which of these two basic approaches they
> prefer? Tom, any thoughts?
>
> David
>
> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>> But consider again the macro definitions which would allow
>>
>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>
>> or
>>
>> DefineIntTable(data, 123, 456, 789);
>>
>> These pass the usefulness test with flying colors, are really easy to
>> explain, and don't have any off-putting squiggles. They solve all the
>> global/local technical difficulties I describe below, yet look comfortably
>> familiar to the beginner's eye. The objection, I believe, is that they look
>> like function calls, and function calls seem wrong floating in space at
>> global scope. But those who raise this objection do so precisely because
>> they are intimate with the language. I suspect beginners would hardly be
>> fazed. And whatever minor confusions the syntax might present are surely
>> easier to document away than, say,
>>
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> My point is that I think the ability to define Flash-based table objects at
>> any scope with a tight and reasonable syntax warrants reconsideration of the
>> Definexxx() style macros, despite the similarity to function calls. Some
>> concepts are compelling enough to suggest tiny stretches of the language
>> boundaries. F() is one of those, and I think tables are too.
>>
>> Mikal
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
They both do the same thing: create an object that allows you to
access data stored in program memory (flash) using the [] array access
syntax. The question is which syntax we prefer for doing so:
DefineIntTable(data, 123, 456, 789);
Or (and here we could replace "PROGMEM" with any other word):
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Or (and again, we can use any names here):
IntData data[] = { 123, 456, 789 };
IntTable sample(data);
Any preferences?
It's apparently impossible to do any of these:
IntTable sample = { 123, 456, 789 };
IntTable sample(123, 456, 789);
IntTable sample = IntTable(123, 456, 789);
IntTable sample = IntTableData(123, 456, 789);
at least, not in way that works at global scope (outside of a
function), which seems like the most important place to be able to
define a lookup table.
David
On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
> I'm a little confused. can you explain the two approaches succinctly?
>
> t.
>
> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>
>> Anyone else have opinions on which of these two basic approaches they
>> prefer? Tom, any thoughts?
>>
>> David
>>
>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>> But consider again the macro definitions which would allow
>>>
>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>
>>> or
>>>
>>> DefineIntTable(data, 123, 456, 789);
>>>
>>> These pass the usefulness test with flying colors, are really easy to
>>> explain, and don't have any off-putting squiggles. They solve all the
>>> global/local technical difficulties I describe below, yet look comfortably
>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>> like function calls, and function calls seem wrong floating in space at
>>> global scope. But those who raise this objection do so precisely because
>>> they are intimate with the language. I suspect beginners would hardly be
>>> fazed. And whatever minor confusions the syntax might present are surely
>>> easier to document away than, say,
>>>
>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>> IntTable sample(data);
>>>
>>> My point is that I think the ability to define Flash-based table objects at
>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>> Definexxx() style macros, despite the similarity to function calls. Some
>>> concepts are compelling enough to suggest tiny stretches of the language
>>> boundaries. F() is one of those, and I think tables are too.
>>>
>>> Mikal
>
>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
These are all baby steps toward std::vector. It might be worth taking some inspiration from that direction, one way or another.
= Mike
On Mar 29, 2011, at 12:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
I don't like the first version because it's unclear that data is {123, 456, 789}. It seems like data is one more element in the intTable. It should be clear that data is not the same class of thing as the things which comprise it.
The nice thing about the PROGMEM keyword is that it makes it explicit that there is something special about this array. Even if I don't yet know what an intTable is, I know there is a difference between
int data[] PROGMEM = { 123, 456, 789 };
and
int data[] = { 123, 456, 789 };
So on the whole I guess that means I prefer:
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
Presumably then when I want to acces the data, I do this:
int foo = sample[1];
Serial.print(foo, DEC);
On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
> They both do the same thing: create an object that allows you to
> access data stored in program memory (flash) using the [] array access
> syntax. The question is which syntax we prefer for doing so:
>
> DefineIntTable(data, 123, 456, 789);
>
> Or (and here we could replace "PROGMEM" with any other word):
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Tom, would you find something like
DefineIntTable(sample, { 123, 456, 789 } );
less objectionable?
In my mind there are two problems with the multiline syntax.
int data[] PROGMEM = { 123, 456, 789 };
IntTable sample(data);
First, it seems harder to explain and conceptualize. What does all that
(apparently superfluous) typing mean? If all I want is to make an integer
table called "sample", why do I have to type 2 lines with "extra" stuff like
"data" and "PROGMEM" (or whatever)?
And pulling back that curtain on these implementation details leads to new
errors.
For example, imagine building a sine table using the above as a reference.
You know that sines are floats and not ints, so you change line 1 to
float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
So far so good, but now you also need to remember to change "IntTable" to
"FloatTable" in line 2, and you also need to make sure that the "data" in
parentheses changes to "sines" to match the array name. And of course the
killer is that
Serial.print(sines[x]);
compiles but fails miserably and inexplicably.
To my mind, its bulk and inherent fragility sink the multiline syntax. But
it's good to talk about.
Mikal
> -----Original Message-----
> From: Tom Igoe [mailto:]
> Sent: Tuesday, March 29, 2011 2:58 PM
> To: David A. Mellis
> Cc: Mikal Hart; Arduino Developers
> Subject: Re: Syntax for PROGMEM Lookup Tables
>
> I don't like the first version because it's unclear that data is {123,
> 456, 789}. It seems like data is one more element in the intTable. It
> should be clear that data is not the same class of thing as the things
> which comprise it.
>
> The nice thing about the PROGMEM keyword is that it makes it explicit
> that there is something special about this array. Even if I don't yet
> know what an intTable is, I know there is a difference between
>
> int data[] PROGMEM = { 123, 456, 789 };
>
> and
>
> int data[] = { 123, 456, 789 };
>
> So on the whole I guess that means I prefer:
>
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Presumably then when I want to acces the data, I do this:
>
> int foo = sample[1];
> Serial.print(foo, DEC);
>
>
> On Mar 29, 2011, at 3:22 PM, David A. Mellis wrote:
>
> > They both do the same thing: create an object that allows you to
> > access data stored in program memory (flash) using the [] array
> access
> > syntax. The question is which syntax we prefer for doing so:
> >
> > DefineIntTable(data, 123, 456, 789);
> >
> > Or (and here we could replace "PROGMEM" with any other word):
> >
> > int data[] PROGMEM = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Or (and again, we can use any names here):
> >
> > IntData data[] = { 123, 456, 789 };
> > IntTable sample(data);
> >
> > Any preferences?
> >
> > It's apparently impossible to do any of these:
> >
> > IntTable sample = { 123, 456, 789 };
> > IntTable sample(123, 456, 789);
> > IntTable sample = IntTable(123, 456, 789);
> > IntTable sample = IntTableData(123, 456, 789);
> >
> > at least, not in way that works at global scope (outside of a
> > function), which seems like the most important place to be able to
> > define a lookup table.
> >
> > David
> >
> > On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <>
> wrote:
> >> I'm a little confused. can you explain the two approaches
> succinctly?
> >>
> >> t.
> >>
> >> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
> >>
> >>> Anyone else have opinions on which of these two basic approaches
> they
> >>> prefer? Tom, any thoughts?
> >>>
> >>> David
> >>>
> >>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <>
> wrote:
> >>>> But consider again the macro definitions which would allow
> >>>>
> >>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998,
> 1.0);
> >>>>
> >>>> or
> >>>>
> >>>> DefineIntTable(data, 123, 456, 789);
> >>>>
> >>>> These pass the usefulness test with flying colors, are really easy
> to
> >>>> explain, and don't have any off-putting squiggles. They solve all
> the
> >>>> global/local technical difficulties I describe below, yet look
> comfortably
> >>>> familiar to the beginner's eye. The objection, I believe, is that
> they look
> >>>> like function calls, and function calls seem wrong floating in
> space at
> >>>> global scope. But those who raise this objection do so precisely
> because
> >>>> they are intimate with the language. I suspect beginners would
> hardly be
> >>>> fazed. And whatever minor confusions the syntax might present are
> surely
> >>>> easier to document away than, say,
> >>>>
> >>>>> int data[] PROGMEM = { 123, 456, 789 };
> >>>>> IntTable sample(data);
> >>>>
> >>>> My point is that I think the ability to define Flash-based table
> objects at
> >>>> any scope with a tight and reasonable syntax warrants
> reconsideration of the
> >>>> Definexxx() style macros, despite the similarity to function
> calls. Some
> >>>> concepts are compelling enough to suggest tiny stretches of the
> language
> >>>> boundaries. F() is one of those, and I think tables are too.
> >>>>
> >>>> Mikal
> >>
> >>
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
On Mar 29, 2011, at 7:55 PM, Mikal Hart wrote:
> Tom, would you find something like
>
> DefineIntTable(sample, { 123, 456, 789 } );
>
> less objectionable?
No, it'd be more objectionable to me. It introduces a new structure of punctuation that adds confusion without clarifying anything. It's almost as bad as my least favorite in Processing, Serial.list()[0]. Way too much packed in there. Which is also why we need a print function for IPAddresses, by the way.
>
> First, it seems harder to explain and conceptualize. What does all that
> (apparently superfluous) typing mean? If all I want is to make an integer
> table called "sample", why do I have to type 2 lines with "extra" stuff like
> "data" and "PROGMEM" (or whatever)?
Actually, more typing is usually easier to explain and conceptualize. Terseness is great for experienced programmers, but for beginners, and especially beginners who don't necessarily want to be programers, verboseness actually works better. You don't have to remember what things mean, you just read the word. And when the punctuation is simple and clearly defined, even better. Multiple brackets make things worse, and grammar forms that do different things but look the same are a disaster.
>
> And pulling back that curtain on these implementation details leads to new
> errors.
>
> For example, imagine building a sine table using the above as a reference.
> You know that sines are floats and not ints, so you change line 1 to
>
> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>
> So far so good, but now you also need to remember to change "IntTable" to
> "FloatTable" in line 2, and you also need to make sure that the "data" in
> parentheses changes to "sines" to match the array name.
That's not such a problem, because there's a parallelism to it. It makes sense that I build an intTable with ints and a floatTable with floats. I don't think it's always necessary to hide things to make them simple. You have to give people credit for intelligence, even when they lack knowledge. A clear grammar that they can figure out is better than a simple one that's harder to expand.
> And of course thekiller is that
> Serial.print(sines[x]);
>
> compiles but fails miserably and inexplicably.
That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
>
>
> To my mind, its bulk and inherent fragility sink the multiline syntax. But
> it's good to talk about.
I'm okay with a single line syntax if it's clearly different from other structures, and grammatically and syntatically straightforward, and reveals how it works through its structure. Dave already shot down some of the possibilities I'd consider, so I won't bother with them.
The two-line PROGMEM syntax isn't perfect, I'll agree. But I think it's better than any of the three options presented so far. I'm happy to see other options, though.
_______________________________________________
Developers mailing list
http://arduino.cc/mailman/listinfo/developers_arduino.cc
)
>> float sines[] PROGMEM = { 0.0, 0.349, ..., 0.9998, 1.0 };
>> And of course thekiller is that
>> Serial.print(sines[x]);
>>
>> compiles but fails miserably and inexplicably.
> That is bad, I agree. however, I fail to understand why that fails while Serial.print(samples[x]); works. You haven't explained that yet.
The compiler does not know where "sines" will be placed in memory; the
linker determines that. The compiler generates the executable code for
this...
Serial.print(sines[x]);
...but leaves a place-holder for the address of "sines". The linker
substitutes the place-holder for the actual address of "sines".
The compiler has absolutely no awareness of PROGMEM data^1 . It sees
"sines" as an ordinary array of floats. The code generated by the
compiler for the "print" reads the value from SRAM. The linker puts
"sines" in Flash and substitutes the place-holder for the address.
Basically, "sines" is stored in Flash but the code reads from SRAM.
^1 Which is why it is impossible to devise a more user friendly syntax
for PROGMEM data.
- Brian
On 30/03/2011, at 3:22 , David A. Mellis wrote:
> int data[] PROGMEM = { 123, 456, 789 };
> IntTable sample(data);
>
> Or (and again, we can use any names here):
>
> IntData data[] = { 123, 456, 789 };
> IntTable sample(data);
To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
One way to mitigate this would be by convention, something like:
IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
IntTable sample(sample_PROGMEM_reference);
Another possible defence of the latter format would be
typedef IntData struct { int value; }
That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
Enjoy,
Peter.
>
> Any preferences?
>
> It's apparently impossible to do any of these:
>
> IntTable sample = { 123, 456, 789 };
> IntTable sample(123, 456, 789);
> IntTable sample = IntTable(123, 456, 789);
> IntTable sample = IntTableData(123, 456, 789);
>
> at least, not in way that works at global scope (outside of a
> function), which seems like the most important place to be able to
> define a lookup table.
>
> David
>
> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>> I'm a little confused. can you explain the two approaches succinctly?
>>
>> t.
>>
>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>
>>> Anyone else have opinions on which of these two basic approaches they
>>> prefer? Tom, any thoughts?
>>>
>>> David
>>>
>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>> But consider again the macro definitions which would allow
>>>>
>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>
>>>> or
>>>>
>>>> DefineIntTable(data, 123, 456, 789);
>>>>
>>>> These pass the usefulness test with flying colors, are really easy to
>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>> global/local technical difficulties I describe below, yet look comfortably
>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>> like function calls, and function calls seem wrong floating in space at
>>>> global scope. But those who raise this objection do so precisely because
>>>> they are intimate with the language. I suspect beginners would hardly be
>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>> easier to document away than, say,
>>>>
>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>> IntTable sample(data);
>>>>
>>>> My point is that I think the ability to define Flash-based table objects at
>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>> boundaries. F() is one of those, and I think tables are too.
>>>>
>>>> Mikal
>>
>>
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
t.
On Mar 30, 2011, at 9:47 PM, Peter N Lewis wrote:
> On 30/03/2011, at 3:22 , David A. Mellis wrote:
>> int data[] PROGMEM = { 123, 456, 789 };
>> IntTable sample(data);
>>
>> Or (and again, we can use any names here):
>>
>> IntData data[] = { 123, 456, 789 };
>> IntTable sample(data);
>
> To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
>
> Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
>
> One way to mitigate this would be by convention, something like:
>
> IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
> IntTable sample(sample_PROGMEM_reference);
>
> Another possible defence of the latter format would be
>
> typedef IntData struct { int value; }
>
> That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
>
> If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
>
> Enjoy,
> Peter.
>
>
>
>>
>> Any preferences?
>>
>> It's apparently impossible to do any of these:
>>
>> IntTable sample = { 123, 456, 789 };
>> IntTable sample(123, 456, 789);
>> IntTable sample = IntTable(123, 456, 789);
>> IntTable sample = IntTableData(123, 456, 789);
>>
>> at least, not in way that works at global scope (outside of a
>> function), which seems like the most important place to be able to
>> define a lookup table.
>>
>> David
>>
>> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>>> I'm a little confused. can you explain the two approaches succinctly?
>>>
>>> t.
>>>
>>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>>
>>>> Anyone else have opinions on which of these two basic approaches they
>>>> prefer? Tom, any thoughts?
>>>>
>>>> David
>>>>
>>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>>> But consider again the macro definitions which would allow
>>>>>
>>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>>
>>>>> or
>>>>>
>>>>> DefineIntTable(data, 123, 456, 789);
>>>>>
>>>>> These pass the usefulness test with flying colors, are really easy to
>>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>>> global/local technical difficulties I describe below, yet look comfortably
>>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>>> like function calls, and function calls seem wrong floating in space at
>>>>> global scope. But those who raise this objection do so precisely because
>>>>> they are intimate with the language. I suspect beginners would hardly be
>>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>>> easier to document away than, say,
>>>>>
>>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>>> IntTable sample(data);
>>>>>
>>>>> My point is that I think the ability to define Flash-based table objects at
>>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>>> boundaries. F() is one of those, and I think tables are too.
>>>>>
>>>>> Mikal
>>>
>>>
>>
>> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
On Thu, Mar 31, 2011 at 7:36 AM, Tom Igoe <> wrote:
> Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
An interactive application with lots of menus/prompts is where I was
forced to learn about PROGMEM. Web applications are pretty verbose,
too, with lots of fixed strings.
I could see a novice hitting either one of those scenarios.
-Jason
kg4wsv
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
In can be useful for things like audio data (either a full sample or a
wave-form shape) or for images or a font to be displayed on an LED
matrix, etc.
I agree, it's not a huge priority, but it's probably useful enough to
include. In part, this is why I like the two-line solution, because
the first line is the existing notation and the second just wraps it
in a way that makes it accessible using a standard syntax. Otherwise,
to get data from a PROGMEM array, you need to do something like
prog_read_byte(table + n) instead of table[n].
David
On Thu, Mar 31, 2011 at 8:36 AM, Tom Igoe <> wrote:
> Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
> t.
>
> On Mar 30, 2011, at 9:47 PM, Peter N Lewis wrote:
>
>> On 30/03/2011, at 3:22 , David A. Mellis wrote:
>>> int data[] PROGMEM = { 123, 456, 789 };
>>> IntTable sample(data);
>>>
>>> Or (and again, we can use any names here):
>>>
>>> IntData data[] = { 123, 456, 789 };
>>> IntTable sample(data);
>>
>> To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
>>
>> Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
>>
>> One way to mitigate this would be by convention, something like:
>>
>> IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
>> IntTable sample(sample_PROGMEM_reference);
>>
>> Another possible defence of the latter format would be
>>
>> typedef IntData struct { int value; }
>>
>> That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
>>
>> If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
>>
>> Enjoy,
>> Peter.
>>
>>
>>
>>>
>>> Any preferences?
>>>
>>> It's apparently impossible to do any of these:
>>>
>>> IntTable sample = { 123, 456, 789 };
>>> IntTable sample(123, 456, 789);
>>> IntTable sample = IntTable(123, 456, 789);
>>> IntTable sample = IntTableData(123, 456, 789);
>>>
>>> at least, not in way that works at global scope (outside of a
>>> function), which seems like the most important place to be able to
>>> define a lookup table.
>>>
>>> David
>>>
>>> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>>>> I'm a little confused. can you explain the two approaches succinctly?
>>>>
>>>> t.
>>>>
>>>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>>>
>>>>> Anyone else have opinions on which of these two basic approaches they
>>>>> prefer? Tom, any thoughts?
>>>>>
>>>>> David
>>>>>
>>>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>>>> But consider again the macro definitions which would allow
>>>>>>
>>>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>>>
>>>>>> or
>>>>>>
>>>>>> DefineIntTable(data, 123, 456, 789);
>>>>>>
>>>>>> These pass the usefulness test with flying colors, are really easy to
>>>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>>>> global/local technical difficulties I describe below, yet look comfortably
>>>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>>>> like function calls, and function calls seem wrong floating in space at
>>>>>> global scope. But those who raise this objection do so precisely because
>>>>>> they are intimate with the language. I suspect beginners would hardly be
>>>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>>>> easier to document away than, say,
>>>>>>
>>>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>>>> IntTable sample(data);
>>>>>>
>>>>>> My point is that I think the ability to define Flash-based table objects at
>>>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>>>> boundaries. F() is one of those, and I think tables are too.
>>>>>>
>>>>>> Mikal
>>>>
>>>>
>>>
>>> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
On Mar 31, 2011, at 9:01 AM, Jason KG4WSV wrote:
> On Thu, Mar 31, 2011 at 7:36 AM, Tom Igoe <> wrote:
>> Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
>
> An interactive application with lots of menus/prompts is where I was
> forced to learn about PROGMEM.
I can see the sense in that.
> Web applications are pretty verbose,
> too, with lots of fixed strings.
Web apps are not a good Arduino app, though. Putting a whole web app on an Arduino is like putting a 5'8" basketball player at center and telling the 7'2" guys not to help him. If you're on the net, use the net for what it's good for. Put your UI on the server, where you have good computational capability for UI, and have a back-end script contact the Arduino, and vice versa, or serve it from an SD card and let the client do the work.
>
> I could see a novice hitting either one of those scenarios.
I think by the time they hit the former, they'd be ready for the current 2-line PROGMEM syntax.
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
So put it in the two-line syntax for 1.0, it's a decent reference, and then get on with other things.
t.
On Mar 31, 2011, at 9:22 AM, David A. Mellis wrote:
> In can be useful for things like audio data (either a full sample or a
> wave-form shape) or for images or a font to be displayed on an LED
> matrix, etc.
>
> I agree, it's not a huge priority, but it's probably useful enough to
> include. In part, this is why I like the two-line solution, because
> the first line is the existing notation and the second just wraps it
> in a way that makes it accessible using a standard syntax. Otherwise,
> to get data from a PROGMEM array, you need to do something like
> prog_read_byte(table + n) instead of table[n].
>
> David
>
> On Thu, Mar 31, 2011 at 8:36 AM, Tom Igoe <> wrote:
>> Can someone give me a good use case for PROGMEM for beginner or intermediate users? This might be a tempest in a teacup, and perhaps we can stick with existing notation if it's not something a lot of novices need.
>> t.
>>
>> On Mar 30, 2011, at 9:47 PM, Peter N Lewis wrote:
>>
>>> On 30/03/2011, at 3:22 , David A. Mellis wrote:
>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>> IntTable sample(data);
>>>>
>>>> Or (and again, we can use any names here):
>>>>
>>>> IntData data[] = { 123, 456, 789 };
>>>> IntTable sample(data);
>>>
>>> To my mind, both of these are ruled out by the fact that data[1] will return random and inexplicable results when the compiler ignores the PROGMEM attribute and simply accesses ram based on the flash address.
>>>
>>> Any user, even an experienced user, could easily assume that data[1] would work, or could even more easily accidentally use data in place of sample.
>>>
>>> One way to mitigate this would be by convention, something like:
>>>
>>> IntData sample_PROGMEM_reference[] = { 123, 456, 789 };
>>> IntTable sample(sample_PROGMEM_reference);
>>>
>>> Another possible defence of the latter format would be
>>>
>>> typedef IntData struct { int value; }
>>>
>>> That way sample_PROGMEM_reference[1] would be a struct, not an int, which should then throw up a compiler error, while IntTable can cheerfully cast it out of existence or just use sample_PROGMEM_reference[1].value.
>>>
>>> If we've got F("string"), then we should try to use the F for the Int table as well to give a hint to the user (FINT, F_INT_TABLE, whatever). Possibly FSTR for the strings and FINT for the int tables.
>>>
>>> Enjoy,
>>> Peter.
>>>
>>>
>>>
>>>>
>>>> Any preferences?
>>>>
>>>> It's apparently impossible to do any of these:
>>>>
>>>> IntTable sample = { 123, 456, 789 };
>>>> IntTable sample(123, 456, 789);
>>>> IntTable sample = IntTable(123, 456, 789);
>>>> IntTable sample = IntTableData(123, 456, 789);
>>>>
>>>> at least, not in way that works at global scope (outside of a
>>>> function), which seems like the most important place to be able to
>>>> define a lookup table.
>>>>
>>>> David
>>>>
>>>> On Tue, Mar 29, 2011 at 11:26 AM, Tom Igoe <> wrote:
>>>>> I'm a little confused. can you explain the two approaches succinctly?
>>>>>
>>>>> t.
>>>>>
>>>>> On Mar 29, 2011, at 9:52 AM, David A. Mellis wrote:
>>>>>
>>>>>> Anyone else have opinions on which of these two basic approaches they
>>>>>> prefer? Tom, any thoughts?
>>>>>>
>>>>>> David
>>>>>>
>>>>>> On Sun, Mar 27, 2011 at 4:21 PM, Mikal Hart <> wrote:
>>>>>>> But consider again the macro definitions which would allow
>>>>>>>
>>>>>>> DefineFloatTable(sines, 0.000, 0.174, 0.349, 0.523, ..., 0.9998, 1.0);
>>>>>>>
>>>>>>> or
>>>>>>>
>>>>>>> DefineIntTable(data, 123, 456, 789);
>>>>>>>
>>>>>>> These pass the usefulness test with flying colors, are really easy to
>>>>>>> explain, and don't have any off-putting squiggles. They solve all the
>>>>>>> global/local technical difficulties I describe below, yet look comfortably
>>>>>>> familiar to the beginner's eye. The objection, I believe, is that they look
>>>>>>> like function calls, and function calls seem wrong floating in space at
>>>>>>> global scope. But those who raise this objection do so precisely because
>>>>>>> they are intimate with the language. I suspect beginners would hardly be
>>>>>>> fazed. And whatever minor confusions the syntax might present are surely
>>>>>>> easier to document away than, say,
>>>>>>>
>>>>>>>> int data[] PROGMEM = { 123, 456, 789 };
>>>>>>>> IntTable sample(data);
>>>>>>>
>>>>>>> My point is that I think the ability to define Flash-based table objects at
>>>>>>> any scope with a tight and reasonable syntax warrants reconsideration of the
>>>>>>> Definexxx() style macros, despite the similarity to function calls. Some
>>>>>>> concepts are compelling enough to suggest tiny stretches of the language
>>>>>>> boundaries. F() is one of those, and I think tables are too.
>>>>>>>
>>>>>>> Mikal
>>>>>
>>>>>
>>>>
>>>> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
|
NewsArc Lists
| Culture Pages
| Computing Archive
| Media-Pages
Link to this page on your blog or website by copying the HTML code below and pasting it into your site:
|
|