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 .. to identify autoscoped constructors #9285

Merged
merged 3 commits into from
Mar 6, 2024
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
8 changes: 4 additions & 4 deletions docs/syntax/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ below.

- **Autoscoped Constructors:** Referencing constructors via their type name may
lead to long and boilerplate code. To simplify referencing constructors when
the _context is known_ a special `~` syntax is supported. Should there be a
the _context is known_ a special `..` syntax is supported. Should there be a
JaroslavTulach marked this conversation as resolved.
Show resolved Hide resolved
method `describe`:

```ruby
Expand All @@ -310,13 +310,13 @@ below.
may use _autoscoped constructors_ and call

```ruby
describe (~Just 5)
describe (..Just 5)
```

the argument `(~Just 5)` is _recorded but not executed_ until it is send to
the argument `(..Just 5)` is _recorded but not executed_ until it is send to
the `describe` method. The argument of the `describe` method is known to be of
type `Maybe` and have `Just` constructor. The _scope_ is now known and the so
far deferred `~` value gets evaluated. `Maybe.Just 5` atom is constructed and
far deferred `..` value gets evaluated. `Maybe.Just 5` atom is constructed and
execution of `describe` method continues with such atom.

- **Body Without Atom Definitions:** If you provide a body and do not define any
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ public class AtomBenchmarks {
autoscoped_generator x i:Integer =
acc = x:List
if i == 0 then acc else
c = ~Cons i acc
c = ..Cons i acc
i1 = i - 1
@Tail_Call autoscoped_generator c i1

res = autoscoped_generator ~Nil length
res = autoscoped_generator ..Nil length
res
""";
private static final String REVERSE_LIST_CODE =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public void lazyConstructorWithNoArgument() {

materialize v:N = v.to_text

create n = N.materialize (~False)
create n = N.materialize (..False)
""")
.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create");
assertTrue("Can evaluate", create.canExecute());
Expand All @@ -69,7 +69,7 @@ public void lazyConstructorWithSingleArg() {

materialize v:M = v.value

create n = M.materialize (~Construct n)
create n = M.materialize (..Construct n)
""")
.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create");
assertTrue("Can evaluate", create.canExecute());
Expand All @@ -92,7 +92,7 @@ public void lazyConstructorWithTwoArgs() {

materialize v:M = [v.v1, v.v2]

create a b = M.materialize (~Construct a b)
create a b = M.materialize (..Construct a b)
""")
.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create");
assertTrue("Can evaluate", create.canExecute());
Expand All @@ -115,7 +115,7 @@ public void lazyConstructorWithTwoArgsCurried() {
materialize v:M = [v.v1, v.v2]

create a b =
v0 = ~Construct
v0 = ..Construct
v1 = v0 a
v2 = v1 b
M.materialize v2
Expand All @@ -141,7 +141,7 @@ public void lazyConstructorWithTwoArgsNamed() {
materialize v:M = [v.v1, v.v2]

create a b =
v0 = ~Construct v2=a v1=b
v0 = ..Construct v2=a v1=b
M.materialize v0
""")
.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create");
Expand All @@ -164,15 +164,15 @@ public void lazyConstructorWithNamedDefaultedArguments() {

materialize v:M = [v.v1, v.v2, v.v3, v.v4]

c0 _ = M.materialize (~Construct)
c1 a = M.materialize (~Construct a)
c12 a b = M.materialize (~Construct a b)
c123 a b c = M.materialize (~Construct a b c)
c1234 a b c d = M.materialize (~Construct a b c d)
c14 a d = M.materialize (~Construct a v4=d)
c13 a c = M.materialize (~Construct a v3=c)
c41 a d = M.materialize ((~Construct v4=d) a)
c31 a c = M.materialize ((~Construct v3=c) a)
c0 _ = M.materialize (..Construct)
c1 a = M.materialize (..Construct a)
c12 a b = M.materialize (..Construct a b)
c123 a b c = M.materialize (..Construct a b c)
c1234 a b c d = M.materialize (..Construct a b c d)
c14 a d = M.materialize (..Construct a v4=d)
c13 a c = M.materialize (..Construct a v3=c)
c41 a d = M.materialize ((..Construct v4=d) a)
c31 a c = M.materialize ((..Construct v3=c) a)
""");

var c0 = module.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "c0");
Expand Down Expand Up @@ -211,7 +211,7 @@ public void wrongConstructorNameYieldsTypeError() {

materialize v:N = v.to_text

create n = N.materialize (~True)
create n = N.materialize (..True)
""")
.invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create");
assertTrue("Can evaluate", create.canExecute());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ loc, meta(), diag()
);
}

private Expression translateCall(Tree ast, boolean isMethod) {
private Expression translateCall(Tree ast, boolean isMethod) throws SyntaxException {
var args = new java.util.ArrayList<CallArgument>();
var hasDefaultsSuspended = false;
var tree = ast;
Expand Down Expand Up @@ -670,6 +670,16 @@ && isDotOperator(oprApp.getOpr().getRight())
var loc = getIdentifiedLocation(oprApp.getLhs());
args.add(new CallArgument.Specified(Option.empty(), self, loc, meta(), diag()));
}
} else if (tree instanceof Tree.OprApp oprApp
&& isDotDotOperator(oprApp.getOpr().getRight())
JaroslavTulach marked this conversation as resolved.
Show resolved Hide resolved
&& oprApp.getRhs() instanceof Tree.Ident ident) {
var methodName = buildName(ident);
func = new Name.MethodReference(
Option.empty(),
methodName,
methodName.location(),
meta(), diag()
);
} else if (args.isEmpty()) {
return null;
} else {
Expand Down Expand Up @@ -1030,16 +1040,6 @@ loc, meta(), diag()
}
case null -> translateSyntaxError(tree, new Syntax.UnsupportedSyntax("Strange unary -"));
};
case Tree.UnaryOprApp un when "~".equals(un.getOpr().codeRepr()) -> {
var methodName = buildName(un.getRhs());
var methodRef = new Name.MethodReference(
Option.empty(),
methodName,
methodName.location(),
meta(), diag()
);
yield methodRef;
}
case Tree.TypeSignature sig -> {
var methodName = buildName(sig.getVariable());
var methodReference = new CallArgument.Specified(
Expand Down Expand Up @@ -1880,6 +1880,10 @@ private static boolean isDotOperator(Token.Operator op) {
return op != null && ".".equals(op.codeRepr());
}

private static boolean isDotDotOperator(Token.Operator op) {
return op != null && "..".equals(op.codeRepr());
}

private static Tree maybeManyParensed(Tree t) {
for (;;) {
switch (t) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ final String getName() {
@Override
@CompilerDirectives.TruffleBoundary
public String toString() {
return "~" + name;
return ".." + name;
}

@ExportMessage
Expand Down
18 changes: 9 additions & 9 deletions test/Base_Tests/src/Semantic/Conversion_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -437,31 +437,31 @@ add_specs suite_builder =

group_builder.specify "Foo.Value as autoscoped" <|

v = ~Value 10
v = ..Value 10
foo = v:Foo
Foo.Value 10 . should_equal foo

group_builder.specify "Autoscope to two different values" <|

v = ~Value 10
v = ..Value 10
foo = v:Foo
bar = v:Bar
Foo.Value 10 . should_equal foo
Bar.Value 10 . should_equal bar

group_builder.specify "Cannot find constructor" <|
v = ~Value 10
v = ..Value 10

b = Panic.recover Any <|
x = v:Back
x

b . should_fail_with Type_Error
msg = b.to_display_text
msg . should_contain "Cannot find constructor ~Value among Back"
msg . should_contain "Cannot find constructor ..Value among Back"

group_builder.specify "Choose first constructor" <|
v = ~Value 10
v = ..Value 10

m_foo (m:Foo|Bar|Back) = m
m_bar (m:Bar|Foo|Back) = m
Expand All @@ -474,7 +474,7 @@ add_specs suite_builder =
m_back_bar v . should_equal <| Bar.Value 10

group_builder.specify "Choose suitable constructor" <|
v = ~Times 10
v = ..Times 10

m_foo (m:Foo|Bar) = m
m_bar (m:Bar|Foo) = m
Expand All @@ -485,8 +485,8 @@ add_specs suite_builder =
m_back v . should_equal <| Back.Times 10

group_builder.specify "Lazy constructor with State" <|
v0 = ~Value
v1 = ~Value 33
v0 = ..Value
v1 = ..Value 33

State.run Number 42 <|
s42 = State.get Number
Expand All @@ -506,7 +506,7 @@ add_specs suite_builder =
foo_vec (v:Vector) = v.map e->
e:Foo . foo

vec = [~Value 3, ~Value 4, ~Value 5]
vec = [..Value 3, ..Value 4, ..Value 5]

foo_vec vec . should_equal [3, 4, 5]

Expand Down
Loading