manuel / wat-js

Concurrency and Metaprogramming for JS
MIT License
259 stars 10 forks source link

Automatic treatment of objects and functions as applicatives #5

Open shadowcat-mst opened 11 years ago

shadowcat-mst commented 11 years ago

As an experiment, I've modified by combine() function thusly:

sub combine {
  my ($e, $k, $f, $cmb, $o) = @_;
  if ($cmb->$_can('wat_combine')) {
    return $cmb->wat_combine($e, $k, $f, $o);
  } elsif (
    blessed($cmb)
    and $o->$_isa('Wat::Cons') and $o->{car}->$_isa('Wat::Sym')
    and $cmb->can(my $method_name = $o->{car}{name})
  ) {
    return nwrap(sub { $cmb->$method_name(@_) })->wat_combine(
             $e, $k, $f, $o->{cdr}
           );
  }
  die "not a combiner: $cmb";
}

which means that if I eval (perlobj method_name arg1 arg2) it "just works". I'm considering doing the same thing to coderefs.

I'm not yet certain this is a good idea, but it feels pretty elegant so far, and requires significantly less thinking when going back and forth between Wat and the host perl enviornment (though I'm very much looking at wat as an embedded strategy engine rather than a complete language, so your view may differ).

shadowcat-mst commented 11 years ago

(if you decide issues are a stupid way to communicate please just tell me how you'd rather do so - seems to be a reasonable-ish approach so far)

manuel commented 11 years ago

I think "embedded strategy engine" captures very well what I have in mind with Wat.

Yes, I have also thought about this topic long and hard... but haven't come to a conclusion yet. On the one hand, the comfort is real. On the other hand, it detracts from the simplicity of the Wat core. Not sure...

shadowcat-mst commented 11 years ago

One of the nice things from my POV is that I can do things like use my http://p3rl.org/curry module to do:

[ def frob-foo [foo curry::frob]]
[ frob-foo 3 ] # calls $foo->frob(3)

The key thing, I think, is considering which dimension to be as simple as possible in - Wat allows things like native objects and functions and etc. to be passed around without them needing to be boxed to make the Wat runtime happy, and being able to avoid needing to jswap() (nwrap in my code for 'native' to be language agnostics) seems in keeping with simplicity on that dimension, at the cost of complexity along the dimension of the implementation of combine().

So I'm not sure "detracts from the simplicity" is quite right, but I'll admit to not being entirely sure either, although since it was a single small isolated commit I'm going to trust in git to make it easy to back out later if the final answer turns out to be "bad idea".

shadowcat-mst commented 11 years ago

Adding in auto-coderef calling and using perl's operator overloading to make it possible to go the other way - i.e. an Apv overloads to a coderef that combines the internals when called - seems to have worked out really nicely.

http://agaton.scsys.co.uk/~matthewt/wat-async

is an example test file that makes use of that plus the continuation mechanism.

Also, so far I appear to still have both feet.