koka-lang / koka

Koka language compiler and interpreter
http://koka-lang.org
Other
3.26k stars 161 forks source link

Suggestion: mask for effect aliases #155

Open anfelor opened 3 years ago

anfelor commented 3 years ago

It is currently impossible to use an effect synonym like st in mask, but that means that one has to mask three effects instead of one. Similar code as in #153:

effect acquire<e>
  fun store-release(free : () -> e ()) : ()

fun run-dsl(dsl : () -> <acquire<e>|e> a, state : ref<h, list<() -> e ()>>) : <read<h>,write<h>,div|e> a
  with fun store-release(f)
    val r = !state
    set(state, Cons(f, r))
  mask<read>{ mask<write>{ mask<div>(dsl) } }

fun with-acquired(dsl : () -> acquire<e> a, inner : a -> e ()) : <div|e> ()
  with run
  val stref = ref(Nil)
  val a = mask<alloc>{ run-dsl(dsl, stref) }
  mask<read>{ mask<write>{ mask<alloc>{ mask<div>{ inner(a) }}}}}

Here it would be preferable to write mask<st> instead of three separate masks on read,write,alloc.

$ koka -l test.kk
compile: test.kk
loading: std/core
loading: std/core/types
loading: std/core/hnd
check  : test
test.kk(19, 9): error: Invalid type
  type context :         mask<st>(fn() { mask<div>(fn() { inner(a) }) }
  type         :         mask<st>(fn() { mask<div>(fn() { inner(a) }) }
  inferred kind: E
  expected kind: X
  because      : Can only inject effect constants (of kind X)
daanx commented 3 years ago

Ouch! thanks for the reports -- it is a busy time for me until ICFP but will look at this later :-)

One problem I can see is that div is not maskable as it never can be handled. (there is only one conceptual builtin handler for this that provides the fix operation)

anfelor commented 3 years ago

@daanx It's not that urgent, I just wanted to note down these issues here :)

anfelor commented 4 months ago

In Koka 3.1.1, writing mask<st> still fails with:

Invalid type
type context :   mask<st>
type         :        st
inferred kind: H -> E
expected kind: X
because      : Can only inject effect constants (of kind X)

while writing mask<st<h>> fails with:

Type.TypeVar.subNew.KindMismatch: length 1: (1033::KCon H |-> 107::KCon V)

CallStack (from HasCallStack):
  error, called at src/Common/Failure.hs:46:12 in koka-3.1.1-GrUKw6cowJ9E7PPCKFMvzQ:Common.Failure
  raise, called at src/Common/Failure.hs:32:5 in koka-3.1.1-GrUKw6cowJ9E7PPCKFMvzQ:Common.Failure
  failure, called at src/Common/Failure.hs:28:11 in koka-3.1.1-GrUKw6cowJ9E7PPCKFMvzQ:Common.Failure
  assertion, called at src/Type/TypeVar.hs:119:13 in koka-3.1.1-GrUKw6cowJ9E7PPCKFMvzQ:Type.TypeVar
  subNew, called at src/Kind/Infer.hs:1136:79 in koka-3.1.1-GrUKw6cowJ9E7PPCKFMvzQ:Kind.Infer

(notice that the latter exception is from an error call and does not render nicely in vscode).