LiveScript icon indicating copy to clipboard operation
LiveScript copied to clipboard

Currying instance methods

Open johngeorgewright opened this issue 11 years ago • 11 comments

I just attempted to use the curry syntax for an instance method and was surprised by the result:

class Dinner
  curry: (meat, flavour)-->
    @ # global scope

  make: ->
    add-flavour = @curry \chicken
    add-flavour \tikka

dinner = new Dinner
dinner.make!

To access the object's instance I have to bind the method:

class Dinner
  curry: (meat, flavour)~~>
    @ # dinner instance

Is this expected behaviour?

johngeorgewright avatar Oct 25 '14 08:10 johngeorgewright

Sounds like a bug.

dead-claudia avatar Oct 27 '14 07:10 dead-claudia

Basically, from what I'm gathering by the compiled output, the issue is that it should be bound always. The difference should be in whether it is bound to the instance or constructor, and it being always bound, IMO, wouldn't be a bad idea.

dead-claudia avatar Jan 13 '15 09:01 dead-claudia

What's happening is the context is being discarded in curry$ because bound isn't set. So, rather than binding the method in the constructor, I think we can just do curry$(function() {}, true) when it's an instance method.

apaleslimghost avatar Jan 13 '15 10:01 apaleslimghost

I wasn't sure exactly how the binding should've been handled, but that sounds like a good idea.

dead-claudia avatar Jan 13 '15 10:01 dead-claudia

Yep, and this way it can still be called in a separate context (curry$ passes down the original calling context), which wouldn't be possible if we did @method = @method.bind this.

I'll put in a pull request probably tomorrow.

apaleslimghost avatar Jan 13 '15 11:01 apaleslimghost

Having battled with this all night (it was inexplicably transforming this into true), I think we'll have to rethink how to do this. Passing bound as true keeps the top-level context (the class instance), but in the case you want to bind the method to something else after partially applying it:

class A
  b: (c, d)--> this

a = new A
e = f: a.b \c
e.f \d #⇒ do we want a or e?

do we want to retain the A context or call it in the e context? The latter makes more sense given Javascript's semantics for this kind of thing.

apaleslimghost avatar Jan 14 '15 23:01 apaleslimghost

if it's bound, you're not allowed to be-bind it.

vendethiel avatar Jan 14 '15 23:01 vendethiel

@vendethiel The question is about the semantics of curried class/instance methods. It appears that currying leads to nonobvious behavior, as detailed here. I don't know of any use cases for not binding an instance method. The case involving a partially applied curry looks ripe for bikeshedding here. It's an incompatibile fix, but it's a useful issue to address.

dead-claudia avatar Jan 15 '15 00:01 dead-claudia

Oh. Alright, that's my bad.

Okay, we have two solutions:

  • always bind curried methods
  • set the object instance "somehow" for the reminder of the currying when it's first called.

vendethiel avatar Jan 15 '15 01:01 vendethiel

With your two options, 1 was already suggested by @quarterto, and 2 will require either a new helper or a partial rewrite of the existing one. If we go with the second, I believe a new helper would be better for compat reasons, since people already directly call the curry helper itself for various reasons (e.g. prelude-ls).

dead-claudia avatar Jan 15 '15 14:01 dead-claudia

@gkz ?

vendethiel avatar Jan 06 '16 22:01 vendethiel