1. 9

Interesting motivation for the (functional, strongly typed) Keli language to use a smalltalk-like syntax:

  • user experience of existing languages
  • lack of clarity around parameters in traditional function application
  • lack of good IDE support

Looking at the examples I wasn’t so convinced anymore that this will overcome the problem it addresses. Still, this is an ambitious and well thought-out project.

  1. 7

    Author seems to miss the advantage of currying and partial application in FP that is enabled with positional arguments. You could adapt currying or partials with this message-based syntax, but I think it’d end up messy.

    As for lack of IDE support, every FP language they list has good IDE support… Haskell in Emacs w/ Intero, F# in Visual Studio, etc.

    I get Emacs seems unfriendly to some people, but the existence of decent tooling there shows IDE support exists and could be provided in friendlier (i.e., GUI-centric) IDEs too.

    1. 6

      In the motivation, the author identifies the 2 big problems with functional programming languages: they use positional arguments (instead of labeled arguments), and they don’t support infix function calls, which means they are not IDE or Intellisense friendly.

      To clarify the second point: In OOP languages, you can write object.method(argument). The ‘method’ is written in infix position, between the object, which is like the first argument, and the remaining arguments. If you just type object., then Intellisense can suggest method names that make sense for the object.

      I don’t know why the author thinks that functional programming languages are missing labeled arguments and infix function calls, and that a new language needs to be invented to fill this hole.

      The usual trick for using labeled arguments in a function call is to pass a record as an argument. For example, in Curv, you write rotate {angle: 45*deg, axis: Z_axis} cube to rotate a cube by 45°. The expression {angle: 45*deg, axis: Z_axis} is a record literal. Modern functional languages have record literals.

      The usual trick for writing infix function calls is to use the “pipe forward” operator, which is >> in Curv, |> in Elm, F# and many other functional languages. In Curv, you can rotate that cube by writing

      cube >> rotate {angle: 45*deg, axis: Z_axis}

      Modern functional languages have a pipe-forward operator. Haskell has another syntax for infixing a function call:

      a `f` b

      is equivalent to f a b. But I haven’t seen that syntax widely copied in other languages.

      1. 1

        In addition to what you said, OCaml supports named parameters similar to Python: is_prefix has type affix:string -> string -> bool and is called is_prefix ~affix:"foo" "foobar". From a real world library.

        merlin supports completion similar to intellisense based on types. If a function expects a t, it’ll suggest functions that produce t ([1]). After a pipe, it’ll suggest functions that accept a parameter matching the input of the pipe ([2]).

        1. 1

          Thanks for the link to Curv, it looks interesting!

        2. 1

          I’m not familiar with Haskell. Is this just a wrapper for Haskell? What is “stack” and why do I need that to install instead of just downloading an executable

          1. 1

            Yeah, stack is a Haskell thing. I don’t speak for Keli, but here’s the URL missing from the Keli documentation: https://docs.haskellstack.org/en/stable/README/

            1. 1

              ah ok - no thanks then - this project looks interesting - but it seems like the whole point is that the syntax is better than haskell

              while that is true - thats point kind of gets lost behind the fact that you still have to use haskell on the backend.

          2. 1

            It seems that labeled function arguments can make the role of arguments more obvious at the call site. In OCaml, which provides labels, this does not work too well when using partial application. But maybe partial application is something the author would discourage anyway. Labels in OCaml can’t be keywords, which exclude in and with, so translating the str.translate with: example is indeed cumbersome.