Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add key functions to Table to make it act as [Column] #3644

Merged
merged 8 commits into from
Aug 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@
- [Updated `Vector.take` and `Vector.drop` and removed their obsolete
counterparts.][3629]
- [Short-hand syntax for `order_by` added.][3643]
- [Expanded `Table.at` to support index access and added `Table.column_count`
method.][3644]

[debug-shortcuts]:
https://github.com/enso-org/enso/blob/develop/app/gui/docs/product/shortcuts.md#debug
Expand Down Expand Up @@ -278,6 +280,7 @@
[3617]: https://github.com/enso-org/enso/pull/3617
[3629]: https://github.com/enso-org/enso/pull/3629
[3643]: https://github.com/enso-org/enso/pull/3643
[3644]: https://github.com/enso-org/enso/pull/3644
[3648]: https://github.com/enso-org/enso/pull/3648

#### Enso Compiler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Standard.Table.Data.Aggregate_Column
import Standard.Table.Internal.Aggregate_Column_Helper
from Standard.Database.Data.Column import Column, Aggregate_Column_Builder
from Standard.Database.Data.Internal.IR import Internal_Column
from Standard.Table.Data.Table import No_Such_Column_Error
from Standard.Table.Errors import No_Such_Column_Error
from Standard.Table.Data.Column_Selector import Column_Selector, By_Index
from Standard.Base.Data.Text.Text_Ordering import Text_Ordering
from Standard.Table.Data.Data_Formatter import Data_Formatter
Expand Down Expand Up @@ -86,12 +86,18 @@ type Table
Returns the column with the given name.

Arguments:
- name: The name of the column to get.
at : Text -> Column ! No_Such_Column_Error
at self name =
candidates = self.internal_columns + self.context.meta_index
internal = candidates.find (p -> p.name == name)
self.make_column internal . map_error (_ -> No_Such_Column_Error name)
- selector: The name or index of the column to get.
at : Text | Integer -> Column ! No_Such_Column_Error | Index_Out_Of_Bounds_Error
at self selector=0 = case selector of
Integer -> self.make_column (self.internal_columns.at selector)
Text ->
candidates = self.internal_columns + self.context.meta_index
internal_column = candidates.find (p -> p.name == selector) . map_error (_ -> No_Such_Column_Error selector)
self.make_column internal_column

## Returns the number of columns in the table.
column_count : Integer
column_count self = self.internal_columns.length

## Returns a new table with a chosen subset of columns, as specified by the
`columns`, from the input table. Any unmatched input columns will be
Expand Down Expand Up @@ -423,7 +429,7 @@ type Table
- index: The column to use as the index of the table.
set_index : Text | Column | Vector Text -> Table
set_index self index = Panic.recover Any <|
new_index = (Helpers.unify_vector_singleton index).map (self.at >> .as_internal)
new_index = (Helpers.unify_vector_singleton index).map ((self.at _) >> .as_internal)
Comment on lines -426 to +432
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the default parameter to at (being 0 to choose first available column), but this has a downside that now we cannot nicely use table.at as a higher order function - if it gets no arguments it will use the defaults - so to pass it as an unapplied function we need to use the _ (or in the future ... or sth) to make sure defaults are not triggered.

I'm not saying this is a problem, especially as our GUI users will probably not use at in this mode too often. Knowing that our rule of thumb is to have default arguments wherever possible, I think we may keep it, but there is a trade-off to make.

Another thing I'm worried about is that if some users start learning about higher order functions they will can really easily get confused with how these default arguments work - but this a bigger problem of language design and I'm not sure if a better solution than we currently have is possible - it is always a trade-off. We probably just need to be careful about these defaults when writing user manuals, to make sure the users understand that they need the underscore to avoid defaults. We may also consider trying to improve the error messages somehow, as currently tracking the Not_Invokable_Error was a bit hard even for me, who I tihnk knows Enso pretty well.

new_ctx = self.context.set_index new_index
new_cols = self.internal_columns.filter col->
turned_into_index = new_index.exists i-> i.name == col.name
Expand Down
68 changes: 23 additions & 45 deletions distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ from Standard.Table.Data.Column_Type_Selection import Column_Type_Selection, Aut
from Standard.Table.Data.Data_Formatter import Data_Formatter
from Standard.Base.Data.Text.Text_Ordering import Text_Ordering
from Standard.Base.Error.Problem_Behavior import Problem_Behavior, Report_Warning
from Standard.Table.Errors import Missing_Input_Columns, Column_Indexes_Out_Of_Range, Duplicate_Type_Selector
from Standard.Table.Errors import Missing_Input_Columns, Column_Indexes_Out_Of_Range, Duplicate_Type_Selector, No_Index_Set_Error, No_Such_Column_Error
import Standard.Table.Data.Match_Columns

import Standard.Table.Data.Column_Name_Mapping
Expand Down Expand Up @@ -238,18 +238,34 @@ type Table
## Returns the column with the given name.

Arguments:
- name: The name of the column being looked up.
- selector: The name or index of the column being looked up.

> Example
Get the names of all of the items from the shop inventory.

import Standard.Examples

example_at = Examples.inventory_table.at "item_name"
at : Text -> Column ! No_Such_Column_Error
at self name = case self.java_table.getColumnOrIndexByName name of
Nothing -> Error.throw (No_Such_Column_Error name)
c -> Column.Column c

> Example
Get the last column.

import Standard.Examples

example_at = Examples.inventory_table.at -1
at : Text | Integer -> Column ! No_Such_Column_Error | Index_Out_Of_Bounds_Error
at self selector=0 = case selector of
Integer ->
java_columns = Vector.Vector self.java_table.getColumns
Column.Column (java_columns.at selector)
Text ->
case self.java_table.getColumnOrIndexByName selector of
Nothing -> Error.throw (No_Such_Column_Error selector)
c -> Column.Column c

## Returns the number of columns in the table.
column_count : Integer
column_count self = self.java_table.getColumns.length

## Returns a new table with a chosen subset of columns, as specified by the
`columns`, from the input table. Any unmatched input columns will be
Expand Down Expand Up @@ -495,7 +511,7 @@ type Table
Nothing -> Nothing
_ -> val.to_text
new_names = self.columns.map mapper
self.take_end (self.length - 1) . rename_columns (Column_Name_Mapping.By_Position new_names) on_problems=on_problems
self.take_end (self.row_count - 1) . rename_columns (Column_Name_Mapping.By_Position new_names) on_problems=on_problems

## ALIAS group, summarize

Expand Down Expand Up @@ -892,17 +908,6 @@ type Table
row_count : Integer
row_count self = self.java_table.rowCount

## Returns the number of rows in this table.

> Example
Count the number of rows in the table.

import Standard.Examples

example_length = Examples.inventory_table.length
length : Integer
length self = self.row_count

## Returns a Table describing this table's contents.

The table lists all columns, counts of non-null items and storage types
Expand Down Expand Up @@ -1140,33 +1145,6 @@ type Table
to_csv : Text
to_csv self = Text.from self (File_Format.Delimited delimiter=",")


## UNSTABLE

An error returned when a non-existent column is being looked up.

Arguments:
- column_name: The name of the column that doesn't exist.
type No_Such_Column_Error column_name

## UNSTABLE

Create a human-readable version of the no such column error.
No_Such_Column_Error.to_display_text : Text
No_Such_Column_Error.to_display_text self =
"The column " + self.column_name + " does not exist."

## UNSTABLE

An error returned when getting an index but no index is set for that table.
type No_Index_Set_Error

## UNSTABLE

Create a human-readable version of the no such column error.
No_Index_Set_Error.to_display_text : Text
No_Index_Set_Error.to_display_text self = "The table does not have an index set."

## UNSTABLE

An error returned when the table contains no rows.
Expand Down
26 changes: 26 additions & 0 deletions distribution/lib/Standard/Table/0.0.0-dev/src/Errors.enso
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,29 @@ Column_Name_Mismatch.handle_java_exception =
cause = caught_panic.payload.cause
Error.throw (Column_Name_Mismatch (Vector.Vector cause.getMissing) (Vector.Vector cause.getExtras) cause.getMessage)
Panic.catch ColumnNameMismatchException handler=throw_column_name_mismatch

## UNSTABLE

An error returned when a non-existent column is being looked up.

Arguments:
- column_name: The name of the column that doesn't exist.
type No_Such_Column_Error column_name

## UNSTABLE

Create a human-readable version of the no such column error.
No_Such_Column_Error.to_display_text : Text
No_Such_Column_Error.to_display_text self =
"The column " + self.column_name + " does not exist."

## UNSTABLE

An error returned when getting an index but no index is set for that table.
type No_Index_Set_Error

## UNSTABLE

Create a human-readable version of the no such column error.
No_Index_Set_Error.to_display_text : Text
No_Index_Set_Error.to_display_text self = "The table does not have an index set."
4 changes: 3 additions & 1 deletion distribution/lib/Standard/Table/0.0.0-dev/src/Main.enso
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Standard.Geo.Geo_Json
import Standard.Table.IO.File_Read
import Standard.Table.IO.File_Format
import Standard.Table.IO.Excel
import Standard.Table.Errors
import Standard.Table.Data.Table
import Standard.Table.Data.Column

Expand All @@ -13,7 +14,8 @@ export Standard.Table.Data.Column
export Standard.Table.IO.File_Read
export Standard.Table.IO.File_Format

from Standard.Table.Data.Table export new, from_rows, join, concat, No_Such_Column_Error, Table
from Standard.Table.Data.Table export new, from_rows, join, concat, Table
from Standard.Table.Errors export No_Such_Column_Error

## ALIAS To Table

Expand Down
2 changes: 1 addition & 1 deletion distribution/lib/Standard/Test/0.0.0-dev/src/Main.enso
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ fail_match_on_unexpected_error error frames_to_skip =
payload = error.catch
loc = Meta.get_source_location 1+frames_to_skip
msg = "An unexpected dataflow error (" + payload.to_text + ") has been matched (at " + loc + ")."
fail msg
fail msg+'\n'+error.get_stack_trace_text


## PRIVATE
Expand Down
Loading