Well, x and y should have different types:

x : [Nat -> Nat] -> Nat // indicating native arity with [] brackets
y : [Nat] -> {Nat} [Nat] -> Nat // indicating captured environment type with {} 
brackets
choose_one : [A -> A -> Bool ] -> A

In f, you have to unify x and y, which in my opinion should fail – but if you 
really want that unification to succeed, the type-checker can go in two 
directions. Either, generate the function
y’ : [Nat -> Nat] -> Nat
y’ [n m] = y n m
Or, the function
                x’ : [Nat] -> {Nat} [Nat] -> Nat
                x’ n = \m . x [n m]

As you can see, with currying syntax you are essentially under-specifying your 
intent. What is more is that you have hidden possible allocations (in the case 
that x’ needs to be selected).

Again, I really don’t think this belongs in a system’s programming language.

PKE

From: bitc-dev [mailto:[email protected]] On Behalf Of William ML 
Leslie
Sent: Tuesday, February 17, 2015 9:53 PM
To: Discussions about the BitC language
Subject: Re: [bitc-dev] Arity inference at call (application) sites

​My concern, Shap, is that there are some cases where template instantiation 
falls down, and one of those cases is where the meet operation or 
let-polymorphism or branching does not adequitely describe the property you're 
trying to maintain.  I get that you can define how this native-arity inference 
behaves at the function call boundary, but the interesting case is the one 
where you combine two results into one.  This is the case I want to pick your 
brain on.

On 18 February 2015 at 02:03, Jonathan S. Shapiro 
<[email protected]<mailto:[email protected]>> wrote:
On Mon, Feb 16, 2015 at 2:57 PM, William ML Leslie 
<[email protected]<mailto:[email protected]>> wrote:
I'm a bit uncomfortable with what happens in the case of let-bound 
native-arity-polymorphic case:
let f = choose_one x y z -- different arities​
in f n m
​​
How do you choose a native arity for the callsite?

In a sense, you don't. The arity of f is determined at its definition. In this 
case, I cannot tell what it is, because I don't know what the return value of 
choose_one is. But it cannot depend on the dynamic branch taken in choose_one, 
because this isn't a lazy language.

​Please: native arity.  The arity of f is 2.  It's the *native arity* we care 
about - the number of arguments that will be consumed by the CALL instruction.  
That is, weather evaluation proceeds as (bitc/call (bitc/call f n) m) or 
(bitc/call f n m).
choose_one returns one of its arguments; and perhaps x has a curried definition 
and y takes two arguments directly.  They have the same type, of course, so 
this is a perfectly reasonable thing to do.  But then what instructions do I 
emit to call f?  It may need to be called twice or once, how do we tell?

The only reasonable answer is that choose_one makes a choice of arity for you.  
But I can't figure out by your rules which arity it will choose.  Simply 
propogating the native arity of the original function couldn't work, because 
the native arity of the selected function depends on a runtime value.


  If you say "it's 2", the algorithm is overspecified.  If you say that depends 
on the dynamic branch taken in choose_one, you can CPS transform and pass *all 
three* continuations.

I'm not understanding this statement. I'm not sure how a dynamic branch in 
choose_one could yield a change in arity.

​It could return functions with the same type but different *native arity*.  
You don't know statically what the native arity of the defined function was.​


   I don't think you want to do that.  Can we adopt a calling convention from 
something like STG or FORTH?

No. We need to be able to do the hardware-preferred (or more precisely: 
conventional compiler preferred) calling convention.

Have I misunderstood how you intend to compile this?

I suspect so, but I haven't done a very good job of describing it. I'll attempt 
to correct that in just a little bit.

​It's this that I want to know about, that I still can't tell from your 
description:
X_t = Nat -> Nat -> Nat

-- These are for illustration purposes only.  In practice, they could be a lot 
more complicated.

x, y : X_t
x n m = n + m -- native-arity = 2

y n = y'      -- native-arity = 1, 1
  where y' m = n + m + 1
choose_one : X_t -> X_t -> Bool -> X_t
choose_one x y z = case z of
  True => x
  _ => y
g z n m = let f = choose_one x y z
          in  f n m   -- how many applications appear in the final 'in' clause? 
 why?

--
William Leslie

Notice:
Likely much of this email is, by the nature of copyright, covered under 
copyright law.  You absolutely MAY reproduce any part of it in accordance with 
the copyright law of the nation you are reading this in.  Any attempt to DENY 
YOU THOSE RIGHTS would be illegal without prior contractual agreement.
_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev

Reply via email to