Skip to content

Commit

Permalink
Remove Array.new and Array.copy and move Vector functions to buil…
Browse files Browse the repository at this point in the history
…tins. (#7147)

- Removed Array methods: `new`, `copy` and `new_[1234]`.
- New builtins for `Vector.insert`, `Vector.remove` and `Vector.flatten`.
- Replaced `Vector_Builder` use of `Array.copy` to a `Vector.Builder` approach.
  • Loading branch information
jdunkerley authored Jul 3, 2023
1 parent 4ccf356 commit 4fbe7e3
Show file tree
Hide file tree
Showing 46 changed files with 488 additions and 387 deletions.
111 changes: 13 additions & 98 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Data/Array.enso
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import project.Data.List.List
import project.Data.Ordering.Ordering
import project.Data.Sort_Direction.Sort_Direction
import project.Data.Pair.Pair
from project.Data.Range.Extensions import all
import project.Data.Range.Range
import project.Data.Text.Text
import project.Data.Vector.Vector
Expand All @@ -15,113 +14,18 @@ import project.Errors.Common.Incomparable_Values
import project.Errors.Common.Not_Found
import project.Errors.Common.Index_Out_Of_Bounds
import project.Errors.Problem_Behavior.Problem_Behavior
import project.Errors.Unimplemented.Unimplemented
import project.Meta
import project.Nothing.Nothing
import project.Panic.Panic

from project.Data.Boolean import Boolean, False
from project.Data.Index_Sub_Range import Index_Sub_Range
from project.Data.Range.Extensions import all

## The type of primitive mutable arrays.
@Builtin_Type
type Array
## PRIVATE
ADVANCED
Creates an array with length 0.

> Example
Create an empty array.

Array.empty
empty : Array
empty = @Builtin_Method "Array.empty"

## PRIVATE
ADVANCED
Creates a new array of length size, with all elements uninitialized.

Arguments:
- size: The size of the array to create.

> Example
Create a new array of size 10.

Array.new 10
new : Integer -> Array
new size = @Builtin_Method "Array.new"

## PRIVATE

Create an array with one element provided.

Arguments:
- item_1: The one element in the array.
new_1 : Any -> Array
new_1 item_1 = @Builtin_Method "Array.new_1"

## PRIVATE

Create an array with two elements provided.

Arguments:
- item_1: The first element.
- item_2: The second element.
new_2 : Any -> Any -> Array
new_2 item_1 item_2 = @Builtin_Method "Array.new_2"

## PRIVATE

Create an array with three elements provided.

Arguments:
- item_1: The first element.
- item_2: The second element.
- item_3: The third element.
new_3 : Any -> Any -> Any -> Array
new_3 item_1 item_2 item_3 = @Builtin_Method "Array.new_3"

## PRIVATE

Create an array with four elements provided.

Arguments:
- item_1: The first element.
- item_2: The second element.
- item_3: The third element.
- item_4: The fourth element.
new_4 : Any -> Any -> Any -> Any -> Array
new_4 item_1 item_2 item_3 item_4 = @Builtin_Method "Array.new_4"

## PRIVATE
Copies from the source array, beginning at the specified position, to the
specified position in the destination array.

Arguments:
- src: The source array.
- source_index: The start position in the src array.
- dest: The destination array.
- dest_index: The start position in the that array.

A subsequence of array elements are copied from the src array to the
dest array. The number of components copied is equal to count. The
components at positions source_index through source_index + count - 1
in the src array are copied into positions dest_index through
dest_index + count - 1, respectively, of the destination array.

If the src and dest arguments refer to the same array, then the copy
is performed as if the components at positions source_index through
source_index + count - 1 are first copied to a temporary array with
length count, and then the contents of the temporary array are copied
into positions dest_index through dest_index + count - 1 of the
destination array.

> Example
Copying elements from one array to another.

Array.copy [1,2,3].to_array 0 (Vector.fill 3 0).to_array 0 3
copy : Array -> Integer -> Array -> Integer -> Integer -> Nothing
copy src source_index dest dest_index count = @Builtin_Method "Array.copy"

## Gets an element from the array at a specified index (0-based).

Arguments:
Expand Down Expand Up @@ -593,6 +497,17 @@ type Array
map_with_index : (Integer -> Any -> Any) -> Vector Any
map_with_index self function = Vector.map_with_index self function

## Creates a new array with the skipping elements until `start` and then
continuing until `end` index.

Arguments:
- start: The index of the first element to include.
- end: The index to stop slicing at.

> Example
Remove the first 2 elements then continue until index 5 from the array.

[1, 2, 3, 4, 5, 6, 7, 8].to_array.slice 2 5 == [3, 4, 5].to_array
slice : Integer -> Integer -> Vector Any
slice self start end = Vector.slice self start end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ type Filter_Condition

## PRIVATE
Creates a Single_Choice Widget for delimiters.
default_widget : Boolean -> Boolean -> Boolean -> Widget
default_widget : Boolean -> Boolean -> Boolean -> Boolean -> Widget
default_widget include_comparable=True include_text=True include_boolean=True include_nullable=True =
options_builder = Vector.new_builder
if include_comparable then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,22 +56,22 @@ fit_least_squares : Vector -> Vector -> Model -> Fitted_Model ! Illegal_Argument
fit_least_squares known_xs known_ys model=Model.Linear =
Illegal_Argument.handle_java_exception <| Fit_Error.handle_java_exception <| case model of
Model.Linear intercept ->
fitted = if intercept.is_nothing then Regression.fit_linear known_xs.to_array known_ys.to_array else
Regression.fit_linear known_xs.to_array known_ys.to_array intercept
fitted = if intercept.is_nothing then Regression.fit_linear known_xs known_ys else
Regression.fit_linear known_xs known_ys intercept
Fitted_Model.Linear fitted.slope fitted.intercept fitted.rSquared
Model.Exponential intercept ->
log_ys = Model.ln_series known_ys "Y-values"
fitted = if intercept.is_nothing then Regression.fit_linear known_xs.to_array log_ys.to_array else
Regression.fit_linear known_xs.to_array log_ys.to_array intercept.ln
fitted = if intercept.is_nothing then Regression.fit_linear known_xs log_ys else
Regression.fit_linear known_xs log_ys intercept.ln
Model.fitted_model_with_r_squared Fitted_Model.Exponential fitted.intercept.exp fitted.slope known_xs known_ys
Model.Logarithmic ->
log_xs = Model.ln_series known_xs "X-values"
fitted = Regression.fit_linear log_xs.to_array known_ys.to_array
fitted = Regression.fit_linear log_xs known_ys
Model.fitted_model_with_r_squared Fitted_Model.Logarithmic fitted.slope fitted.intercept known_xs known_ys
Model.Power ->
log_xs = Model.ln_series known_xs "X-values"
log_ys = Model.ln_series known_ys "Y-values"
fitted = Regression.fit_linear log_xs.to_array log_ys.to_array
fitted = Regression.fit_linear log_xs log_ys
Model.fitted_model_with_r_squared Fitted_Model.Power fitted.intercept.exp fitted.slope known_xs known_ys
_ -> Error.throw (Illegal_Argument.Error "Unsupported model.")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type Rank_Method
Error.throw (Incomparable_Values.Error exc.payload.getLeftOperand exc.payload.getRightOperand)

handle_cmp_exc <| handle_nullpointer <|
java_ranks = Rank.rank input.to_array java_method
java_ranks = Rank.rank input java_method
Vector.from_polyglot_array java_ranks

type Statistic
Expand Down Expand Up @@ -302,19 +302,19 @@ wrap_java_call ~function =
Given two series, get a computed CorrelationStatistics object
calculate_correlation_statistics : Vector -> Vector -> CorrelationStatistics
calculate_correlation_statistics x_data y_data =
wrap_java_call <| CorrelationStatistics.compute x_data.to_array y_data.to_array
wrap_java_call <| CorrelationStatistics.compute x_data y_data

## PRIVATE
Given two series, get a compute the Spearman Rank correlation
calculate_spearman_rank : Vector -> Vector -> Decimal
calculate_spearman_rank x_data y_data =
wrap_java_call <| CorrelationStatistics.spearmanRankCorrelation x_data.to_array y_data.to_array
wrap_java_call <| CorrelationStatistics.spearmanRankCorrelation x_data y_data

## PRIVATE
Given a set of series get CorrelationStatistics objects
calculate_correlation_statistics_matrix : Vector Vector -> Vector CorrelationStatistics
calculate_correlation_statistics_matrix data =
data_array = Vector.new data.length i->(data.at i).to_array . to_array
data_array = Vector.new data.length i->(data.at i).to_array
stats_array = wrap_java_call <| CorrelationStatistics.computeMatrix data_array
Vector.new stats_array.length i->(Vector.from_polyglot_array (stats_array.at i))

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
## Methods for operating on `Text` in Enso.

import project.Any.Any
import project.Data.Array.Array
import project.Data.Index_Sub_Range.Index_Sub_Range
import project.Data.Locale.Locale
from project.Data.Range.Extensions import all
import project.Data.Range.Range
import project.Data.Text.Case.Case
import project.Data.Text.Case_Sensitivity.Case_Sensitivity
Expand Down Expand Up @@ -38,6 +36,7 @@ import project.Nothing.Nothing
from project.Data.Boolean import Boolean, True, False
from project.Data.Json import Json, Invalid_JSON, JS_Object
from project.Data.Numbers import Decimal, Integer, Number, Number_Parse_Error
from project.Data.Range.Extensions import all

from project.Widget_Helpers import make_delimiter_selector, make_date_format_selector, make_date_time_format_selector, make_time_format_selector

Expand Down Expand Up @@ -473,8 +472,8 @@ Text.replace self term replacement case_sensitivity=Case_Sensitivity.Sensitive o
case use_regex of
False -> if term.is_empty then self else
array_from_single_result result = case result of
Nothing -> Array.empty
_ -> Array.new_1 result
Nothing -> []
_ -> [result]
spans_array = case case_sensitivity of
Case_Sensitivity.Sensitive -> case only_first of
False -> Text_Utils.span_of_all self term
Expand Down Expand Up @@ -673,7 +672,7 @@ Text.bytes self encoding on_problems=Problem_Behavior.Report_Warning =
@encoding Encoding.default_widget
Text.from_bytes : Vector Integer -> Encoding -> Problem_Behavior -> Text
Text.from_bytes bytes encoding on_problems=Problem_Behavior.Report_Error =
result = Encoding_Utils.from_bytes bytes.to_array (encoding . to_java_charset)
result = Encoding_Utils.from_bytes bytes (encoding . to_java_charset)
if result.warnings.is_nothing then result.result else
on_problems.attach_problems_after result.result [Encoding_Error.Error result.warnings]

Expand Down Expand Up @@ -736,7 +735,7 @@ Text.char_vector self = Vector.from_polyglot_array (Text_Utils.get_chars self)
This is useful for low-level operations, such as binary data encoding and
decoding.
Text.from_char_vector : Vector Integer -> Text
Text.from_char_vector chars = Text_Utils.from_chars chars.to_array
Text.from_char_vector chars = Text_Utils.from_chars chars

## Returns a vector containing integers representing the Unicode codepoints of
the input text.
Expand All @@ -761,7 +760,7 @@ Text.codepoints self = Vector.from_polyglot_array (Text_Utils.get_codepoints sel
Converting a vector of codepoints back into a text.
Text.from_codepoints [129318, 127996, 8205, 9794, 65039]
Text.from_codepoints : Vector Integer -> Text
Text.from_codepoints codepoints = Text_Utils.from_codepoints codepoints.to_array
Text.from_codepoints codepoints = Text_Utils.from_codepoints codepoints

## ALIAS Check Prefix

Expand Down Expand Up @@ -1301,7 +1300,7 @@ Text.locate_all self term="" case_sensitivity=Case_Sensitivity.Sensitive = if te
Case_Sensitivity.Default -> self.locate term Case_Sensitivity.Sensitive
Case_Sensitivity.Sensitive ->
codepoint_spans = Vector.from_polyglot_array <| Text_Utils.span_of_all self term
grahpeme_ixes = Vector.from_polyglot_array <| Text_Utils.utf16_indices_to_grapheme_indices self (codepoint_spans.map .codeunit_start).to_array
grahpeme_ixes = Vector.from_polyglot_array <| Text_Utils.utf16_indices_to_grapheme_indices self (codepoint_spans.map .codeunit_start)
## While the codepoint_spans may have different code unit lengths
from our term, the `length` counted in grapheme clusters is
guaranteed to be the same.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ type Utf_16_Span
grapheme_ix = Text_Utils.utf16_index_to_grapheme_index self.parent self.start
Span.Value (grapheme_ix.up_to grapheme_ix) self.parent
False ->
grapheme_ixes = Text_Utils.utf16_indices_to_grapheme_indices self.parent [self.start, self.end - 1].to_array
grapheme_ixes = Text_Utils.utf16_indices_to_grapheme_indices self.parent [self.start, self.end - 1]
grapheme_first = grapheme_ixes.at 0
grapheme_last = grapheme_ixes.at 1
## We find the grapheme index of the last code unit actually contained within our span and set the
Expand Down
47 changes: 15 additions & 32 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Data/Vector.enso
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,11 @@ import project.Panic.Panic
import project.Random
import project.Warning.Warning

from project.Data.Range.Extensions import all

## We have to import also conversion methods, therefore, we import all from the Ordering
module
from project.Data.Ordering import all
from project.Data.Boolean import Boolean, True, False
from project.Data.Index_Sub_Range import Index_Sub_Range, take_helper, drop_helper
from project.Data.Filter_Condition import unify_condition_or_predicate, unify_condition_predicate_or_element
from project.Data.Index_Sub_Range import Index_Sub_Range, take_helper, drop_helper
from project.Data.Ordering import all
from project.Data.Range.Extensions import all

polyglot java import java.lang.IndexOutOfBoundsException
polyglot java import org.enso.base.Array_Builder
Expand Down Expand Up @@ -568,13 +565,7 @@ type Vector a

[[1, 2, 3], [4, 10], [], [0], [0]] . flatten == [1, 2, 3, 4, 10, 0, 0]
flatten : Vector Any
flatten self =
length = self.fold 0 acc-> elem-> acc + elem.length
arr = Array.new length
self.fold 0 i-> vec->
Array.copy vec.to_array 0 arr i vec.length
i + vec.length
Vector.from_polyglot_array arr
flatten self = @Builtin_Method "Vector.flatten"

## Applies a function to each element of the vector, returning the `Vector`
of results.
Expand Down Expand Up @@ -691,13 +682,7 @@ type Vector a
[1] + [2]
+ : Vector Any -> Vector Any
+ self that = case that of
_ : Vector ->
self_len = self.length
that_len = that.length
arr = Array.new (self_len + that_len)
Array.copy self.to_array 0 arr 0 self_len
Array.copy that.to_array 0 arr self_len that_len
Vector.from_polyglot_array arr
_ : Vector -> Vector.insert_builtin self self.length that
_ : Array -> self + Vector.from_polyglot_array that
_ -> Error.throw (Type_Error.Error Vector that "that")

Expand All @@ -723,11 +708,10 @@ type Vector a
if used_index < 0 || used_index > self_len then Error.throw (Index_Out_Of_Bounds.Error at self_len+1) else
if used_index == self_len then self + [item] else
if used_index == 0 then [item] + self else
arr = Array.new (self_len + 1)
Array.copy self.to_array 0 arr 0 used_index
Array.copy [item].to_array 0 arr used_index 1
Array.copy self.to_array used_index arr (used_index + 1) (self_len - used_index)
Vector.from_polyglot_array arr
Vector.insert_builtin self used_index [item]

## PRIVATE
insert_builtin vec at values = @Builtin_Method("Vector.insert_builtin")

## Removes the item at the given index from the vector.

Expand All @@ -740,10 +724,10 @@ type Vector a
self_len = self.length
used_index = if at < 0 then self_len + at else at
if used_index >= self_len || used_index < 0 then Error.throw (Index_Out_Of_Bounds.Error at self_len) else
arr = Array.new (self_len - 1)
Array.copy self.to_array 0 arr 0 used_index
Array.copy self.to_array (used_index + 1) arr used_index (self_len - used_index - 1)
Vector.from_polyglot_array arr
Vector.remove_builtin self used_index

## PRIVATE
remove_builtin vec at = @Builtin_Method "Vector.remove_builtin"

## When `self` is a vector of text values, concatenates all the values by
interspersing them with `separator`.
Expand All @@ -763,8 +747,7 @@ type Vector a
if self.length == 1 then prefix + self.at 0 + suffix else
prefix + self.at 0 + (1.up_to self.length . fold "" acc-> i-> acc + separator + self.at i) + suffix

## PRIVATE
Creates a new vector with the skipping elements until `start` and then
## Creates a new vector with the skipping elements until `start` and then
continuing until `end` index.

Arguments:
Expand Down Expand Up @@ -1113,7 +1096,7 @@ type Builder
## This workaround is needed because
`self.java_builder.addAll subrange.to_array` fails with
`Unsupported argument types: [Array]`.
append_result = self.java_builder.appendTo subrange.to_array
append_result = self.java_builder.appendTo subrange
append_result.if_not_error self

## PRIVATE
Expand Down
2 changes: 1 addition & 1 deletion distribution/lib/Standard/Base/0.0.0-dev/src/Meta.enso
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ type Constructor
new : Vector -> Any
new self fields =
ctor = self.value ...
new_atom ctor fields.to_array
new_atom ctor fields

## ADVANCED
Returns the type that this constructor is a part of.
Expand Down
Loading

0 comments on commit 4fbe7e3

Please sign in to comment.