Clojure

Forbid varargs defprotocol/definterface method declarations because those cannot be defined anyway

Details

  • Type: Enhancement Enhancement
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Duplicate
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
  • Patch:
    Code

Description

Protocol, interface method declarations don't allow for varags. Currently, for example

  (defprotocol FooBar
    (foo [this & more]))

compiles just fine, and & is interpreted as a usual argument that happens to be
named & without special meaning. But clearly, the user wanted to specify a
varags parameter here. The same applies to definterface.

Similarly, providing method implementations via defrecord, deftype, and reify
don't allow for varags (but dynamic extensions via extend do).

So this patch makes defprotocol and definterface throw an
IllegalArgumentException if a user tries to use varargs in method signatures.

Similarly, defrecord, deftype, and reify throw an IllegalArgumentException if
any method implementation arglist contains a varargs argument.

This patch is a cut-down variant of my patch to http://dev.clojure.org/jira/browse/CLJ-1024
which has been reverted shortly before Clojure 1.5 was released. The CLJ-1024 patch
was the same as this one, but it has also forbidden destructuring in defprotocol and
definterface. This was a bit too much, because although destructuring has no
semantic meaning with method declarations, it still can serve a documentation purpose.

This has been discussed on the list: https://groups.google.com/d/topic/clojure-dev/qjkW-cv8nog/discussion

Activity

Tassilo Horn made changes -
Field Original Value New Value
Description Protocol, interface method declarations don't allow for varags. Currently, for example

{noformat}
  (defprotocol FooBar
    (foo [this & more]))
{noformat}

compiles just fine, and {{&}} is interpreted as a usual argument that happens to be
named {{&}} without special meaning. But clearly, the user wanted to specify a
varags parameter here. The same applies to definterface.

Similarly, providing method implementations via defrecord, deftype, and reify
don't allow for varags (but dynamic extensions via extend do).

So this patch makes defprotocol and definterface throw an
IllegalArgumentException if a user tries to use varargs in method signatures.

Similarly, defrecord, deftype, and reify throw an IllegalArgumentException if
any method implementation arglist contains a varargs argument.

This patch is a cut-down variant of my patch to http://dev.clojure.org/jira/browse/CLJ-1024
which has been reverted shortly before Clojure 1.5 was released. The CLJ-1024 patch
was the same as this one, but it has also forbidden destructuring in {{defprotocol}} and
{{definterface}}. This was a bit too much, because although destructuring has no
semantic meaning with method declarations, it still can serve an documentation purpose.

This has been discussed on the list: https://groups.google.com/d/topic/clojure-dev/qjkW-cv8nog/discussion
Protocol, interface method declarations don't allow for varags. Currently, for example

{noformat}
  (defprotocol FooBar
    (foo [this & more]))
{noformat}

compiles just fine, and {{&}} is interpreted as a usual argument that happens to be
named {{&}} without special meaning. But clearly, the user wanted to specify a
varags parameter here. The same applies to {{definterface}}.

Similarly, providing method implementations via defrecord, deftype, and reify
don't allow for varags (but dynamic extensions via extend do).

So this patch makes {{defprotocol}} and {{definterface}} throw an
{{IllegalArgumentException}} if a user tries to use varargs in method signatures.

Similarly, {{defrecord}}, {{deftype}}, and {{reify}} throw an {{IllegalArgumentException}} if
any method implementation arglist contains a varargs argument.

This patch is a cut-down variant of my patch to http://dev.clojure.org/jira/browse/CLJ-1024
which has been reverted shortly before Clojure 1.5 was released. The CLJ-1024 patch
was the same as this one, but it has also forbidden destructuring in {{defprotocol}} and
{{definterface}}. This was a bit too much, because although destructuring has no
semantic meaning with method declarations, it still can serve a documentation purpose.

This has been discussed on the list: https://groups.google.com/d/topic/clojure-dev/qjkW-cv8nog/discussion
Tassilo Horn made changes -
Description Protocol, interface method declarations don't allow for varags. Currently, for example

{noformat}
  (defprotocol FooBar
    (foo [this & more]))
{noformat}

compiles just fine, and {{&}} is interpreted as a usual argument that happens to be
named {{&}} without special meaning. But clearly, the user wanted to specify a
varags parameter here. The same applies to {{definterface}}.

Similarly, providing method implementations via defrecord, deftype, and reify
don't allow for varags (but dynamic extensions via extend do).

So this patch makes {{defprotocol}} and {{definterface}} throw an
{{IllegalArgumentException}} if a user tries to use varargs in method signatures.

Similarly, {{defrecord}}, {{deftype}}, and {{reify}} throw an {{IllegalArgumentException}} if
any method implementation arglist contains a varargs argument.

This patch is a cut-down variant of my patch to http://dev.clojure.org/jira/browse/CLJ-1024
which has been reverted shortly before Clojure 1.5 was released. The CLJ-1024 patch
was the same as this one, but it has also forbidden destructuring in {{defprotocol}} and
{{definterface}}. This was a bit too much, because although destructuring has no
semantic meaning with method declarations, it still can serve a documentation purpose.

This has been discussed on the list: https://groups.google.com/d/topic/clojure-dev/qjkW-cv8nog/discussion
Protocol, interface method declarations don't allow for varags. Currently, for example

{noformat}
  (defprotocol FooBar
    (foo [this & more]))
{noformat}

compiles just fine, and {{&}} is interpreted as a usual argument that happens to be
named {{&}} without special meaning. But clearly, the user wanted to specify a
varags parameter here. The same applies to {{definterface}}.

Similarly, providing method implementations via {{defrecord}}, {{deftype}}, and {{reify}}
don't allow for varags (but dynamic extensions via {{extend}} do).

So this patch makes {{defprotocol}} and {{definterface}} throw an
{{IllegalArgumentException}} if a user tries to use varargs in method signatures.

Similarly, {{defrecord}}, {{deftype}}, and {{reify}} throw an {{IllegalArgumentException}} if
any method implementation arglist contains a varargs argument.

This patch is a cut-down variant of my patch to http://dev.clojure.org/jira/browse/CLJ-1024
which has been reverted shortly before Clojure 1.5 was released. The CLJ-1024 patch
was the same as this one, but it has also forbidden destructuring in {{defprotocol}} and
{{definterface}}. This was a bit too much, because although destructuring has no
semantic meaning with method declarations, it still can serve a documentation purpose.

This has been discussed on the list: https://groups.google.com/d/topic/clojure-dev/qjkW-cv8nog/discussion
Hide
Stuart Halloway added a comment -

I think that this patch would be much more helpful to users if it reported the problem form (both name and params).

(And I wonder if we should be using ex-info for all errors going forward.)

Show
Stuart Halloway added a comment - I think that this patch would be much more helpful to users if it reported the problem form (both name and params). (And I wonder if we should be using ex-info for all errors going forward.)
Stuart Halloway made changes -
Approval Incomplete [ 10006 ]
Hide
Tassilo Horn added a comment -

New version of the patch that mentions both method name and argument vector, and uses ex-info as Stu suggested.

Show
Tassilo Horn added a comment - New version of the patch that mentions both method name and argument vector, and uses ex-info as Stu suggested.
Tassilo Horn made changes -
Tassilo Horn made changes -
Attachment 0001-Protocol-interface-method-declarations-don-t-allow-f.patch [ 11860 ]
Hide
Andy Fingerhut added a comment -

Presumuptuously changing Approval from Incomplete back to None, since the reason for marking it Incomplete seems to have been addressed with a new patch.

Show
Andy Fingerhut added a comment - Presumuptuously changing Approval from Incomplete back to None, since the reason for marking it Incomplete seems to have been addressed with a new patch.
Andy Fingerhut made changes -
Approval Incomplete [ 10006 ]
Alex Miller made changes -
Labels enhancement patch protocols
Hide
Andy Fingerhut added a comment -

I have not investigated the reason yet, but patch 0001-Protocol-interface-method-declarations-don-t-allow-f.patch no longer applies cleanly after the latest commits to Clojure master on Oct 25 2013.

Show
Andy Fingerhut added a comment - I have not investigated the reason yet, but patch 0001-Protocol-interface-method-declarations-don-t-allow-f.patch no longer applies cleanly after the latest commits to Clojure master on Oct 25 2013.
Hide
Tassilo Horn added a comment -

I'm closing this issue in favor of CLJ-888 which is about the very same issue and contains a more recent patch that also contains test cases.

Show
Tassilo Horn added a comment - I'm closing this issue in favor of CLJ-888 which is about the very same issue and contains a more recent patch that also contains test cases.
Tassilo Horn made changes -
Resolution Duplicate [ 3 ]
Status Open [ 1 ] Resolved [ 5 ]

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: