Repository: hylang/hy

Issue:
kwapply doesn't translate a key '-' to '_'
arguments of a function are translated from '-', symbols also are translated, but strings are not, so having a key 'my-key-argument' won't be translated to 'my_key_argument' having a:
    TypeError: myfunc() got an unexpected keyword argument 'my-key-argument'



Discussion:
Hummmm.

An interesting question, this.

whats the status of this?

On hold, i guess. I don't know of anyone working on it

This should be pretty easy to implement, I believe, and also a great and easy candidate for the Grand Language Cleanup! I'll have a go at it.

What do y'all think about this:

``` hy
(apply some-function [] {"a-b" 1})
(apply some-function [] {:a-b 1})
```

both translating to:

``` python
some_function(*[], **{"a_b": 1})
```


Resolving patch:
diff --git a/hy/compiler.py b/hy/compiler.py
--- a/hy/compiler.py
+++ b/hy/compiler.py
@@ -38,6 +38,8 @@
 
 from hy.errors import HyCompileError, HyTypeError
 
+from hy.lex.parser import hy_symbol_mangle
+
 import hy.macros
 from hy._compat import (
     str_type, long_type, PY27, PY33, PY3, PY34, PY35, raise_empty)
@@ -1640,7 +1642,21 @@ def compile_apply_expression(self, expr):
                 ret = stargs + ret
 
         if expr:
-            kwargs = self.compile(expr.pop(0))
+            kwargs = expr.pop(0)
+            if isinstance(kwargs, HyDict):
+                new_kwargs = []
+                for k, v in kwargs.items():
+                    if isinstance(k, HySymbol):
+                        pass
+                    elif isinstance(k, HyString):
+                        k = HyString(hy_symbol_mangle(str_type(k))).replace(k)
+                    elif isinstance(k, HyKeyword):
+                        sym = hy_symbol_mangle(str_type(k)[2:])
+                        k = HyString(sym).replace(k)
+                    new_kwargs += [k, v]
+                kwargs = HyDict(new_kwargs).replace(kwargs)
+
+            kwargs = self.compile(kwargs)
             if PY35:
                 kwargs_expr = kwargs.force_expr
                 ret.expr.keywords.append(
diff --git a/hy/lex/parser.py b/hy/lex/parser.py
--- a/hy/lex/parser.py
+++ b/hy/lex/parser.py
@@ -45,6 +45,22 @@
 )
 
 
+def hy_symbol_mangle(p):
+    if p.startswith("*") and p.endswith("*") and p not in ("*", "**"):
+        p = p[1:-1].upper()
+
+    if "-" in p and p != "-":
+        p = p.replace("-", "_")
+
+    if p.endswith("?") and p != "?":
+        p = "is_%s" % (p[:-1])
+
+    if p.endswith("!") and p != "!":
+        p = "%s_bang" % (p[:-1])
+
+    return p
+
+
 def set_boundaries(fun):
     @wraps(fun)
     def wrapped(p):
@@ -297,22 +313,7 @@ def t_identifier(p):
     if obj.startswith(":"):
         return HyKeyword(obj)
 
-    def mangle(p):
-        if p.startswith("*") and p.endswith("*") and p not in ("*", "**"):
-            p = p[1:-1].upper()
-
-        if "-" in p and p != "-":
-            p = p.replace("-", "_")
-
-        if p.endswith("?") and p != "?":
-            p = "is_%s" % (p[:-1])
-
-        if p.endswith("!") and p != "!":
-            p = "%s_bang" % (p[:-1])
-
-        return p
-
-    obj = ".".join([mangle(part) for part in obj.split(".")])
+    obj = ".".join([hy_symbol_mangle(part) for part in obj.split(".")])
 
     return HySymbol(obj)
 


Test patch:
diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy
--- a/tests/native_tests/language.hy
+++ b/tests/native_tests/language.hy
@@ -309,7 +309,10 @@
   (assert (= (apply sumit [] {"a" 1 "b" 1 "c" 2}) 4))
   (assert (= (apply sumit ((fn [] [1 1])) {"c" 1}) 3))
   (defn noargs [] [1 2 3])
-  (assert (= (apply noargs) [1 2 3])))
+  (assert (= (apply noargs) [1 2 3]))
+  (defn sumit-mangle [an-a a-b a-c a-d] (+ an-a a-b a-c a-d))
+  (def Z "a_d")
+  (assert (= (apply sumit-mangle [] {"an-a" 1 :a-b 2 'a-c 3 Z 4}) 10)))
 
 
 (defn test-apply-with-methods []