WithName table alias fails at column reference

The AddRow method requires a table reference and a column reference. If a table alias is created using WithName, said alias works as a table target, but column references on that table cause AddRow to fail.

See here:

Hi @Christian_Rodriguez3,
it’s a good point and it needs some clarification; but I don’t think this is a bug.

The WithName() function does take the value of the expression.
In your case, [Ex. WithName].WithName(exName, exName)exName is the actual instance of the table; i.e. the full set or rows (and therefore you can access all its properties).

However - as you correctly pointed out - when referring to a column in the typical [Table].[Column] syntax, [Table] (and [Column]) is an object reference (not its value).
(You can omit the table reference at all, if there are not naming conflicts).

[Ex. WithName].AddRow(
  [Ex. WithName].[Col 1], // or simply [Col 1] - is the column reference
  4 
)

and

[Ex. WithName].WithName(exTable,
  extTable.AddRow(   // here it's valid because you are adding a row to a set of rows (the value of exTable)
    [Col 1], 4
  )
)

To better clarify:

  1. Within row modifications (add/modify) [Ex WithName].[Col 1] as first parameter, is an object reference
  2. Out of that context, [Ex WithName].[Col 1] → is a list of [Col 1] values
  3. extTable.[Col 1]always outputs a list of [Col 1] values (as above).

I hope this helps.
Cheers!

Yeah @Federico.Stefanato has the right of it. Although, I’m also bummed by this. Wish Coda could identify when I mean a pointer and when I mean a value. Clearly, if I’m putting something in the first slot of AddRow I mean a pointer to a column.

Thanks for the response. If I understand the argument you’re making correctly, I still think the behavior is inconsistent. Apologies in advance if I’m missing or misunderstanding!

This is the signature of the AddRow method. In this context, it expects that expressions passed for the table and column are both references:

AddRow(table <reference>, column <reference>, columnValue)

You stated that:

The WithName() function does take the value of the expression.

So here’s the question: why is the value of a table an instance of that table (which is still a reference to the table) but the value of a column is just the list of its rows and not an instance of that column?

For consistent behavior I would assume that both are either “passed by value” / greedily evaluated or both are “passed by reference” / lazily evaluated based on the context in which the expression is used.

Put more clearly (I hope):

By Value / Greedy Evaluation

  • WithName(Table,...) returns a shallow copy (i.e. duplicate table data instead of create table view) whose data can be accessed, but changes made to the copy don’t impact the original table

  • WithName(Column,...) returns a shallow copy of the column whose data can be accessed (current behavior)

By Reference / Lazy Evaluation

  • WithName(Table,...) returns a pointer to a table whose data can be accessed and any changes made to it do impact the original table (current behavior)

  • WithName(Column,...) returns a pointer to the column and depending on the context may be used as a pointer (like for AddRow) or for its values (for lookups, filters, etc).

It may be the case that there is no “value / shallow copy” version of a table, only views or new tables, and that’s why the behavior seems to make sense from your perspective, but to me it looks like WithName is behaving inconsistently.

1 Like

Hi @Christian_Rodriguez3,
sorry for the late reply.

I recognize there is a misunderstanding: every time you have the same notation for different purposes, the risk of this happening is high…

I’m not finding that specific signature for the AddRow() method :thinking:

In the Formula Reference, we have AddRow(table, column, columnValue).

The table parameter is actually an instance, i.e. a set of rows of the same table: as a matter of fact, you can have a View or the result of a Filter() and access all rows operations (AddRow(), AddOrModifyRows(), DeleteRows()).

Meaning that:

MyTable.Filter(...).ModifyRows(column, ColumnValue)

and

MyTable.Filter(...).withName(myTable,
 myTable.ModifyRows(column, ColumnValue)

are the same thing.

On the other hand, the column parameter is indeed a reference to its meta-information.
And the only way to get its reference is through the notation [Base Table Name].[Column Name].

You can’t even using a [View Name].[Column Name] for that table (you can try and you’ll get an error saying “AddRow expects parameter column to be a column, but found value” for that specific reason).

This is maybe the crucial point of the misunderstanding:
Anywhere else if you use [Base Table Name].[Column Name], you’ll get a list of Column Name values.
However, within [Modify-|AddOrModify-|AddRow-]s() methods - as a column parameter - it has a different meaning.

But it’s not WithName()'s fault per se, it’s this single way to address two things related to a column.

I hope I clarified the point and not messed up things worse. :grinning_face_with_smiling_eyes:

I was also expecting lazy evaluation. What I thought would happen is that Coda would say, “Hey, looks like you referenced a column, I’ll hold onto that for you.”

And then when I went to use the column in a non-action formula it would say something to me like, “Ohh… you want to use formulas on the data. Let me go grab the list of data for you.”

But of course, if I were to use that column reference in an action like AddRow I expect it to instead say, “Ha! This formula requires a reference to a table. I’ll pass the reference itself instead of grabbing the data that the reference points to.”