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

A whole bunch of language tweaks and syntax updates #222

Merged
merged 95 commits into from Aug 6, 2018

Conversation

Projects
None yet
4 participants
@pchiusano
Copy link
Member

pchiusano commented Aug 2, 2018

Here's a quick summary. We can try out new syntax changes and make tweaks, I would not consider any of this set in stone. Open to bikeshedding on the syntax if anyone has other ideas.

  • Syntax sugar for delayed computations (() -> a): 'a, !a, and delay <layout block>
  • Sequence a type can be written as [a].
  • Added some missing Sequence functions (drop, ++).
  • Type signatures are generalized over any lowercase free variables. Example: a -> a becomes forall a . a -> a.
  • namespace blocks, ex: namespace Foo where blah = 24 is a circuitous way of saying Foo.blah = 24. They can be nested.
  • imports, via the use keyword, syntax use Math.sqrt to allow sqrt to be referenced unqualified, other examples: use Sequence.++ (import a single operator), use Sequence.++ map filter (an operator and some other names). One or more use statements can appear at start of any block. No wildcard imports yet. Later imports shadow earlier ones.

Some more notes on the syntax for delayed computations

  • '43 is syntax for () -> 43. It has highest possible precedence, so get-or-else '43 x parses as get-or-else ('43) x. You might use the idiom '(foo x) if you want to pass around a delayed call to foo x.
  • The type 'x is sugar for () -> x. It has higher precedence than -> but lower precedence than application, so the type fork : '{Remote} a -> {Remote} (Future a) parses as ('{Remote} a) -> {Remote} (Future a).
  • !x is syntax for x(). It has same precedence as ', so at !spawn '(factorial 22) parses as at (spawn ()) (() -> factorial 22).
  • delay is like let, it introduces a layout block, but wraps the whole block in a delay. Example:
go : '{IO} ()
go = delay
  x = 1
  launch (x + 1)

I feel like we might want to give delay higher precedence than function application, so you can say things like fork delay <layout block on next line>.

Implementation notes -

  • All the syntax changes were just parser changes, no AST or typechecker changes.
  • It is awkward having to know the Reference and constructor id of any pattern - it means you need to know about all data types before you start parsing terms. This is responsible for the restriction that use statements have to appear first in a block.
  • We might want delays to have a separate AST node rather than just being syntax sugar. This would be an easy refactoring for later.

pchiusano and others added some commits Jul 30, 2018

wip
Adding some machinery so we can detect and do something about existen…
…tials with attached Blanks when they pass out of scope, tests still pass
Split `Blank` up into `Recorded` and non-recorded portion, this lets …
…us give a more precise type for `SolvedBlank` notes

Also changed naming - `blank` is a noop in the typechecker, `placeholder` is like GHC holes, and `resolve` is used for type-directed term resolution
@pchiusano

This comment has been minimized.

Copy link
Member Author

pchiusano commented on f23ca96 Aug 1, 2018

@runarorama just calling your attention to this - now that doRetract looks for those recorded existentials passing out of scope so it can note their types, we want the main entry point to the typechecker to retract the whole context when it completes. The ensures any existentials we might have wanted to record are noted.

@pchiusano

This comment has been minimized.

Copy link
Member Author

pchiusano commented on 0566c26 Aug 1, 2018

@runarorama previously we had data Blank loc = Placeholder | Remember loc String | Resolve loc String which was awkward because when the typechecker records a SolvedBlank note, it should only be one of Remember or Resolve. So I split up the Blank type.

Also did some bikeshedding on names, got rid of remember, it's now called placeholder, and blank is the same meaning as before, the dummy term which is ignored during typechecking.

aryairani and others added some commits Aug 1, 2018

Merge branch 'topic/type-directed' of github.com:unisonweb/unison int…
…o topic/pretty-errors

# Conflicts:
#	parser-typechecker/src/Unison/Type.hs
#	parser-typechecker/src/Unison/UnisonFile.hs
@atacratic

This comment has been minimized.

Copy link
Contributor

atacratic commented Aug 3, 2018

Looking at the fork example above, I wonder if the ' apostrophe syntax is definitely better than the syntax used by Frank? Frank's use of 'suspenders' { } for delay makes it easy to see what is being delayed without parsing for precedence.

I think Frank's rendering of fork would be

fork : { [Remote] a } -> [Remote] (Future a)

(Excuse my gatecrashing this PR! Love all the progress you're making - really seems to be steaming along at the moment 😀)

@aryairani

This comment has been minimized.

Copy link
Contributor

aryairani commented Aug 3, 2018

@atacratic Gatecrashing is welcome 😁 We are pondering the suggestion now.

@pchiusano

This comment has been minimized.

Copy link
Member Author

pchiusano commented Aug 3, 2018

Yeah, we are currently using {} for term level effect values, but maybe can change that syntax or overload it somehow...

@atacratic

This comment has been minimized.

Copy link
Contributor

atacratic commented on unison-src/map-reduce.u in 30dcb4c Aug 4, 2018

You're not actually using f in this function :-) I think you need a case to handle getting down to single-element lists.

This comment has been minimized.

Copy link
Contributor

atacratic replied Aug 4, 2018

Also maybe it would work to use the existing Sequence.halve directly - matching on ([], []) instead of None.

@atacratic

This comment has been minimized.

Copy link
Contributor

atacratic commented on unison-src/map-reduce.u in 30dcb4c Aug 4, 2018

I don't think it helps to use fork here, given the forking going on in par-apply?

@atacratic

This comment has been minimized.

Copy link
Contributor

atacratic commented on unison-src/map-reduce.u in 30dcb4c Aug 4, 2018

(You're not using at in this example at the moment.)

@atacratic

This comment has been minimized.

Copy link
Contributor

atacratic commented on unison-src/map-reduce.u in 30dcb4c Aug 4, 2018

I understood this better when I read it as 'Spawn a new node, with identifier of type n'. Maybe tweak the comment?

@pchiusano

This comment has been minimized.

Copy link
Member Author

pchiusano commented Aug 6, 2018

hey going to merge this. @atacratic thanks for comments, that file was a major work in progress and not surprised parts of it were nonsense. :)

Re: syntax, I got rid of delay keyword, just have ' bind looser than keyword-based layout constructs like let, case, handle. So you can say spawn 'let <blah> or spawn 'case x of, no special rule needed.

@pchiusano pchiusano merged commit dde2414 into master Aug 6, 2018

2 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
continuous-integration/travis-ci/push The Travis CI build passed
Details

@aryairani aryairani deleted the topic/delay branch Aug 14, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.