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

Use only Type instances as keys for State #7585

Merged
merged 3 commits into from
Aug 16, 2023
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,7 @@
- [Using official BigInteger support][7420]
- [Allow users to give a project other than Upper_Snake_Case name][7397]
- [Support renaming variable or function][7515]
- [Only use types as State keys][7585]

[3227]: https://github.com/enso-org/enso/pull/3227
[3248]: https://github.com/enso-org/enso/pull/3248
Expand Down Expand Up @@ -1048,6 +1049,7 @@
[7420]: https://github.com/enso-org/enso/pull/7420
[7397]: https://github.com/enso-org/enso/pull/7397
[7515]: https://github.com/enso-org/enso/pull/7515
[7585]: https://github.com/enso-org/enso/pull/7585

# Enso 2.0.0-alpha.18 (2021-10-12)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ from project.Errors.Common import Uninitialized_State

Arguments:
- key: The key to associate your local_state with in the environment.
It is recommended that types be used as keys.
Use types as keys.
Copy link
Member Author

Choose a reason for hiding this comment

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

The signature of run : Any -> Any -> Any -> Any remains unchanged, as we don't have any type for type Some_Type.

- local_state: The value to associate with key.
- computation: The computation to execute in the local state
environment.
Expand Down
10 changes: 5 additions & 5 deletions distribution/lib/Standard/Database/0.0.0-dev/src/Data/SQL.enso
Original file line number Diff line number Diff line change
Expand Up @@ -158,23 +158,23 @@ optimize_fragments : Vector SQL_Fragment -> Vector SQL_Fragment
optimize_fragments fragments =
builder = Vector.new_builder
go elem =
last_part = State.get SQL_Fragment.Code_Part
last_part = State.get SQL_Fragment
Copy link
Member Author

Choose a reason for hiding this comment

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

Code_Part is an atom constructor - that's a singleton. We could allow atom constructors as keys, but then there is problem with argumentless constructors like Boolean.True - they are immediately converted to Atom during Enso execution and atoms in general aren't singletons.

Restricting keys to types is simpler.

case elem of
SQL_Fragment.Code_Part code ->
new_part = case last_part of
Nothing -> SQL_Fragment.Code_Part code
SQL_Fragment.Code_Part other -> SQL_Fragment.Code_Part other+code
State.put SQL_Fragment.Code_Part new_part
State.put SQL_Fragment new_part
SQL_Fragment.Interpolation _ ->
case last_part of
Nothing -> Nothing
SQL_Fragment.Code_Part _ ->
builder.append last_part
State.put SQL_Fragment.Code_Part Nothing
State.put SQL_Fragment Nothing
builder.append elem
State.run SQL_Fragment.Code_Part Nothing <|
State.run SQL_Fragment Nothing <|
fragments.each go
last_part = State.get SQL_Fragment.Code_Part
last_part = State.get SQL_Fragment
case last_part of
Nothing -> Nothing
SQL_Fragment.Code_Part _ -> builder.append last_part
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.ReportPolymorphism;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
Expand All @@ -12,6 +13,9 @@
import org.enso.interpreter.dsl.Suspend;
import org.enso.interpreter.node.BaseNode;
import org.enso.interpreter.node.callable.thunk.ThunkExecutorNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.state.State;

@BuiltinMethod(
Expand All @@ -35,7 +39,7 @@ abstract Object execute(
Object doExisting(
VirtualFrame frame,
State state,
Object key,
Type key,
Object local,
Object computation,
@Bind("state.getContainer()") State.Container data,
Expand All @@ -54,7 +58,7 @@ Object doExisting(
Object doFresh(
VirtualFrame frame,
State state,
Object key,
Type key,
Object local,
Object computation,
@Bind("state.getContainer()") State.Container data,
Expand All @@ -67,4 +71,11 @@ Object doFresh(
objects.removeKey(data, key);
}
}

@Fallback
Object doNonType(State state, Object key, Object local, Object computation) {
var b = EnsoContext.get(this).getBuiltins();
var payload = b.error().makeUnsupportedArgumentsError(new Object[] {key}, "Use type as a key.");
throw new PanicException(payload, this);
}
}
2 changes: 2 additions & 0 deletions test/Tests/src/Main.enso
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import project.Runtime.Lazy_Spec
import project.Runtime.Lazy_Generator_Spec
import project.Runtime.Managed_Resource_Spec
import project.Runtime.Ref_Spec
import project.Runtime.State_Spec
import project.Runtime.Stack_Traces_Spec

import project.System.Environment_Spec
Expand Down Expand Up @@ -135,6 +136,7 @@ main = Test_Suite.run_main <|
Runtime_Spec.spec
Self_Type_Spec.spec
Span_Spec.spec
State_Spec.spec
Encoding_Spec.spec
Text_Sub_Range_Spec.spec
Managed_Resource_Spec.spec
Expand Down
25 changes: 25 additions & 0 deletions test/Tests/src/Runtime/State_Spec.enso
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from Standard.Base import all

import Standard.Base.Runtime.State
import Standard.Base.Errors.Common.Unsupported_Argument_Types

from Standard.Test import Test, Test_Suite
import Standard.Test.Extensions

spec = Test.group "State" <|
Test.specify "Type as a key" <|
s = State.run Test 42 <|
State.get Test
s . should_equal 42

Test.specify "string as a key" <|
s n = State.run "my_state" n <|
State.get "my_state"

p = Panic.catch Unsupported_Argument_Types (s 42) err->
err.payload

Meta.type_of p . should_equal Unsupported_Argument_Types


main = Test_Suite.run_main spec
Loading