kitten icon indicating copy to clipboard operation
kitten copied to clipboard

Avoid syntax that requires local variables

Open trans opened this issue 7 years ago • 3 comments

Are there (or can there be) combinator forms of conditionals? They way things are, it looks like one must use local variables if there are any conditionals.

trans avatar Dec 09 '16 14:12 trans

Sort of. If you omit the condition from an if, it’s taken from the stack, and the branches can have any stack effect as long as they match.

define cond<R..., S...> (R..., (R... -> S...), (R... -> S...), Bool -> S...) {
  -> t, f, x;
  if (x) { t } else { f } call
}

=>

define cond (…) {
  -> t, f;
  if { t } else { f } call
}

=>

define cond (…) {
  if { drop } else { swap drop } call
}

And a missing or empty else is the same as the identity function:

=>

define cond (…) {
  if (not) { swap }
  drop call
}

I just don’t tend to use this style in examples much. There are some things that require locals, like capturing a value in a closure or vector, but you can wrap these in combinators. I’ve been thinking about how to fix those cases, too.

evincarofautumn avatar Dec 09 '16 21:12 evincarofautumn

Great. That works.

trans avatar Dec 10 '16 18:12 trans

Currently, list literals cannot draw elements from the stack. I propose using the _ placeholder to denote this. Just as for local variables, elements would be popped in the same order they were pushed:

[1, 2, 3]
// ==
1 [_, 2, 3]
1 2 [_, _, 3]
1 2 3 [_, _, _]
2 [1, _, 3]

define singleton<T> (T -> List<T>):
  -> x;
  [x]
// ==
define singleton<T> (T -> List<T>):
  [_]

This could also be done for quotations:

define quote<T> (T -> (-> T)):
  -> x;
  { x }
// ==
define quote<T> (T -> (-> T)):
  { _ }

And for string literals, with an escape \_:

instance show<A, B> (Pair<A, B> -> List<Char>):
  unpair -> x, y;
  [x show, " ", y show, " pair"] concat
// ==
instance show<A, B> (Pair<A, B> -> List<Char>):
  unpair "\_ \_ pair"

This might be a point of confusion for some people, however, because the syntax for operator sections is still (x @) / (@ x), not (x @ _) / (_ @ x). Changing to the latter would allow for prefix and postfix operators in addition to infix operators, but I feel that would introduce too much complexity for little benefit.

evincarofautumn avatar Feb 01 '17 23:02 evincarofautumn