
Motivation – Keli Language - azhenley
https://keli-language.gitbook.io/doc/
======
misja111
I think it's great that Keli is designed with IDE support in mind. However I
believe that this is only half of the reason why FP still doesn't really break
through in the corporate world.

The other reason is that many FP users are too enthusiastic about creating
abstractions. This is of course something that FP is exceptionally well suited
for. An api that was written to simply process a list of Orders into a Report
might be abstracted into a fold on some monad, which at first seems a great
idea. But if you're not careful, readability suffers a lot. It's much easier
to get to know an application when its code deals with business objects that
you already understand well, than to read hundreds of lines of code that deal
only with abstractions.

Maybe there should be a new edition of Clean Code written specifically for FP,
to address this anti pattern.

By the way this problem is not unique for FP, OOP suffered the same problem in
the past. But the OOP community learned from its mistakes and now most
developers know to 'prefer composition over inheritance', for instance.

~~~
cannabis_sam
> An api that was written to simply process a list of Orders into a Report
> might be abstracted into a fold on some monad, which at first seems a great
> idea. But if you're not careful, readability suffers a lot. It's much easier
> to get to know an application when its code deals with business objects that
> you already understand well, than to read hundreds of lines of code that
> deal only with abstractions.

Do you have a code example? It would be interesting to see what this kind of
code looks like.

Personally, I find complaining about a ”fold over a monad” to be equivalent to
complaining about an ”integer indexed loop over an array”. It’s a pretty
straightforward implementation detail that have very little to do with your
business logic.

And business logic is far, far easier to model using ADTs (it’s literally just
AND and OR, applied to data structures) than confounding object inheritance
hierarchies.

In fact, I’ve seen a lot more unnecessarily abstracted garbage (usually
“design pattern” workarounds to limitations in the object model) in just about
every oop based web framework I’ve worked with.

~~~
HelloNurse
I'd prefer readability to suffer because the fold over a monad needs something
clever that requires a bit of reasoning to understand than because vast
amounts of "readable" boilerplate (for example, trivial getters and setters)
hide a needle in a haystack.

~~~
qppo
folding over a monad (or any other combinator) doesn't require extra reasoning
or anything clever, that's the point.

~~~
JadeNB
I think HelloNurse's point was less that a fold is inherently clever or subtle
(as you say, it isn't), and more that, if there _is_ something clever or
subtle involved, the lesser verbosity of the fold makes it easier to see than
would a more familiar, boilerplate-heavy approach in which the clever or
subtle point could be lost.

------
enricozb
When giving an example on how infix notation reads better:

    
    
        // This is obviously not too right
        ",".splitBy("1,2,3,4,5")
    
        // This should be right, because it reads out more naturally
        "1,2,3,4,5".splitBy(",")
    

It's funny that in Python split works this way but join doesn't. This is
because in the case of split both arguments are strings, but for join one of
the arguments is a Sequence, which is a general protocol rather than a class.

The proposed solution by Keli is to be inspired by the Smalltalk-style message
syntax:

    
    
        'Hello world' replace: 'Hello' with: 'Bye'
    

I think, in general, requiring named arguments is a good thing. Swift does it,
and in codebases with a decent amount of TLC, it looks great.

Function calls are one of the weird places were the syntax of the language
rarely helps you figure out what is going on, and for the most part is just a
sequence of human-written names one after another, and in languages with
custom operators it could be even terser.

In comparison, if-statements, loops, pattern matching, etc. were (hopefully)
designed to be expressive. I think by requiring named arguments, function
calls will also be much more readable, relying less on an active human effort
to do so.

~~~
laumars
I get this might just boil down to preference but I absolutely hate named
parameters. They’re biased towards new users of a language and quickly become
painful to write once you’re familiar with the function call.

Plus they don’t always improve writability outside of IDEs because you then
have to memorise the parameter names and in some functions there’s several
terms that could equally apply (if you’re using an IDE with hinting then the
advantages become moot as the same IDE would hint the order of parameters).

~~~
WillPostForFood
>I absolutely hate named parameters. They’re biased towards new users of a
language and quickly become painful to write once you’re familiar with the
function call.

It is a fair complaint, but don't you think this is offset almost entirely by
a good IDE?

~~~
lostcolony
First, having spent the past two years in IntelliJ with Java, no. I still
would have much preferred named parameters to having to worry about the order
(and still occasionally mixing them up when they're not unique types, and only
finding out when things fail).

Second, if a language is heavily reliant on features from an IDE, yeah, I'll
echo that's a badly designed language.

~~~
WillPostForFood
Sorry, I agree with you. I like named parameters as well. I meant the overhead
of having to type them is pretty much entirely offset by a good IDE that fills
them out for you. I don't think there is a downside unless you are coding in a
text editor.

------
hashbig
Elm single handedly got me into functional programming. Everything from the
syntax to the standard library. I haven’t used a language that was that
elegant and delightful to use perhaps since I discovered Ruby.

It makes me really sad that Elm turned to this niche language/framework that
it is today. I had hoped for it to grow someday to have a mobile target in
addition to web, to be able to use it on the server, hell even to be able to
use it to build systems. So much wasted potential.

~~~
Kaze404
I also love Elm, but the fact that it is a niche language _now_ doesn't mean
it's all it ever will be. There's nothing really stopping anyone from adapting
Elm to the server for example, but the reason it hasn't been done yet is
because it's best to focus on solving one problem at a time. If Evan just
translated the Node standard api 1:1 for example, it wouldn't be Elm _or_ Node
and there would be no reason to use it.

~~~
pcstl
There's the core team, which is extremely unfriendly to any kind of user-
driven development of the language.

The whole reason Elm has been stuck in a niche when it had _huge_ hype around
2015 and everyone was sure it would be the "next big thing" on the front-end
is that the developers have tried to keep full control of the language and
keep shooting down proposals by users. It's either their way or the highway.

~~~
lalos
I'm familiar with those controversies, and most if not all of them I would
side with the Elm team. The thing is that, yes it is nice to get user-driven
development but they seemed to be proposing to bring back concepts from their
OO experience and/or baking in features that should not be part of the core
library and are easily implemented if you understand how Elm is wired. Seems
like these users are excited to contribute but need to get more familiar with
FP before contributing to a higher level FP library. I remember one where the
proposal could be easily be implemented generically with ports and any other
JS library instead of bringing some weird binding logic to A specific JS
library. Add the fact that devs from the FP world are concise with their
explanations and you have a recipe for miscommunication problems when trying
to explain why that idea is DOA to someone not familiar with core FP concepts.

~~~
Latty
Eh, it isn't just that though. I recently made a big push to try and get a
relatively small change through (setting CSS Custom Properties), which is a
big blocker for using a lot of web components (which is officially suggested
as a way to deal with interop for the language), and will likely block
interaction with future web APIs that use custom properties.

I went through and collected up the reasons to do it, distilled it down and
gave examples as requested by the core team and got lots of positive feedback
from the community, and just got no response from the core devs and nothing
happened.

I agree not all changes people propose are good, I _like_ the fact the
language is opinionated and doesn't include half-baked ideas, but there is
literally no way to get anything through into Elm core, any attempt to do the
legwork is just ignored and thrown away. It is a one-man project and that's
it, but they pretend that isn't the case.

Honestly, the answer is probably an unstable fork of the language for more
experimentation and development, which to be fair, anyone could do¸ but
obviously maintaining that would be a lot of work (I don't want to imply that
the core Elm team have some responsibility to do it).

------
fsloth
The author lists F# as not IDE friendly. I find this categorization
inaccurate.

F# works great with Visual Studio, and especially well with intellisense.

F# was designed as industrial language from the beginning, and high quality
tooling is a large part of that.

It might just be me, though, maybe other people use the language in ways that
don't work that well there.

~~~
pjmlp
The only issue with F# is that it is a bit the black swan of Microsoft
languages on .NET, so it doesn't get all the toys that C#, VB.NET and even
C++/CLI get to play with.

~~~
fsloth
I don't think F# needs toys, though. The language is so well put together you
don't miss much IDE assist anyway, except to point to you where your code will
have problems compiling.

~~~
pjmlp
Sure it does, a language alone isn't much help if it only gets a tiny slice of
the ecosystem.

No .NET Native, GUI designers, WCF/gRPC, EF designers, Blend, WinUI tooling,
ASP.NET templates,... hinders adoption at corporate level.

~~~
Cybiote
My experience is that, compared to most functional languages, F# has a great
IDE experience in Rider, Visual Studio and VS Code. But when compared to big
industry focused languages, like C# and Java, tooling is middling at best.

Ironically, despite .NET core being an excellent runtime, it suffers stigma
from being assumed to be too tied to Microsoft platforms. This means,
depending on your angle, F# lacking specialized ties to the Windows specific
tooling you mention need not be considered a disadvantage.

------
nephanth
I personally don’t think keli is fixing the right problems: I’m personally an
ocaml user, and I don’t see what keli adds to ocaml.

They cite positional parameters (that they call "prefix notation"… i wonder
why ?) but ocaml already has support for named parameters (you can write
things like split ~on:"," "a, b, c" for example) Moreover, guessing the order
of parameters is generally not that hard :

— If you have good intellisense your IDE will tell you which parameter is
which (how they are called in doc)

— If you have good intellisense, your ide will tell you the type of function,
which, with strict typing is sufficient in a lot of cases (think "send :
Unix.socket -> string -> unit", the type tells you the order of arguments)

— with named parameters, you don’t have to look up the order of parameters…
but you have to look up their names, same problem

— This last one is pretty subjective, but in a lot of cases you can guess the
order of parameters by thinking "on which argument does it make sense to do
partial application ?" `splitBy ","` makes sense, `splitBy "a, b, c"` doesn’t
really… so "," is the first argument (but that is subjective)

For IDE support, with the right tools, in my experience it is pretty good
(ocaml-lsp or merlin do the job pretty well, and strict typing often allow for
better intellisense than on non-functional languages)

Though there we arrive at the real problem I’ve experienced : the tooling.
It’s not actually that bad. more like it’s badly explained. how do you know
that you are supposed to install

— opam for package management (and reinstall ocaml via opam)

— dune for building

— utop as a REPL, because the basic REPL sucks

— batteries or janestreet-core for "standard library" because the standard
library sucks (and which one anyway ?)

Plus these tools are hard to use at beginning / have a learning curve. (why
can’t creating a project be as simple as \- type "cargo new project" -> now
you automatically have a project dir with a local opam switch, an opam file, a
dune file, an example program, and basic utilities installed in that switch ?
)

Personally, I think that’s what fp lacks the most right now (though I’m
probably influenced a lot by ocaml) : easy to use and flat-learning curve
tooling

~~~
marmaduke
This is impressively compréhensive and covers everything I thought of while
reading the post. I also agree that OCaml needs a one click to
opam+dune+utop+batteries+Merlin+editor experience, but new tools like
[https://www.gitpod.io/](https://www.gitpod.io/) help since your project can
just describe everything declaratively and spin up a working environment. I
expect this sort of tooling will help with a lot of languages which are not
really integrated by default

------
grantjpowell
On the topic of language IDE support. One of the things I've noticed from
working in a few languages professionally (Python, Ruby, Java, Elixir) is that
the level of power required in an IDE seems to be a function of the language.

My observation was that to feel comfortable in Java I tended to require a very
powerful IDE (Intellej) to deal with refactoring and appeasing the type
system.

When I write Elixir, I feel comfortable using a much less powerful (from a
language integration standpoint) Vim, mostly due to the constraints Elixir has
in the language. In Elixir, there is no mutable state, I can feel confident
that the only things affecting a function are the things in front of my face
when reading it. Elixir's alias/import syntax make it pretty easy to jump to
the file that has a function definition in.

I think FP languages tend to have an edge in how much power an IDE is required
to have, because those languages tend to have features like immutability and
composable higher order functions)

~~~
nerdponx
The biggest advantage of an IDE for me, in any language, is the ability to
rename/move/refactor things across multiple files in a project correctly. I
feel notably less capable in this regard when using Vim versus a "full" IDE,
no matter what the context or project.

~~~
grantjpowell
Yeah, this exact flow was a pain for me in switching from vscode to vim full
time.

My flow now is to search for a bunch of instances using the fzf plugin
([https://github.com/junegunn/fzf.vim](https://github.com/junegunn/fzf.vim))
and open them into the quickfix list, then do something like

    
    
        :%s/old/new/gce | :w | :bnext

~~~
throwawaw
Is fzf buying you anything over just using :grep? (If speed is the issue, the
magic words are `set grepprg='rg --vimgrep'`, after which it's actually
usable.)

~~~
grantjpowell
I've never really explored the native grep functionality, so its possible I'm
missing something.

The two features I really like about fzf are

1.) the preview window (visible here
[https://github.com/junegunn/fzf](https://github.com/junegunn/fzf))

2.) Fuzzy finding/multi-selection/gradual refinement of search terms

~~~
throwawaw
Nope, you're not missing anything, then. Maybe I am -- I use the fzf plugin,
but only for finding files. Is this (build_quickfix_list) what you're using?
[https://github.com/junegunn/fzf/blob/master/README-
VIM.md#ex...](https://github.com/junegunn/fzf/blob/master/README-
VIM.md#examples)

------
gmfawcett
The author lists Ocaml as "non-IDE-friendly." This is not my experience. Ocaml
is one of the most IDE friendly languages I have in my toolkit right now --
not just functional languages, but all of them. Ocaml + Emacs + Merlin is
stable, accurate, very fast (responsive), and easy to set up and configure.

Plus, named and named-optional parameters are supported in the language, and
can be used to good effect for disambiguating function parameters of similar
type (the split, join problem).

~~~
hashbig
Compare that to JavaScript where you can literally just install vscode and
node and you’re up and running. Not to mention that you could pop open a
console in any browser and execute code.

I love OCaml as a language but we have to admit that the developer experience
just sucks.

For something to be simple, a 10 year old kid needs to be able to figure it
out. That’s how languages get adopted.

~~~
gmfawcett
Really? I've had much, much worse developer experiences with other languages.
With opam and dune wrapping the default toolchain, honestly it's a pleasure to
work with these days.

(I feel obliged to give an example of what I think is a bad developer
experience, and I would point at Haskell. There are far too many toolchain
variations to choose from, all of which seem to be in active use -- cabal,
cabal-v2, stack, cabal-v2+nix, stack+nix; ghcid, ghcide, etc. etc. Once your
choices are made and your stack is configured, you'll be okay, except for the
inordinately long build times. But in my experience, it can be a real nuisance
to come back to a half-finished Haskell project -- say, on a new machine --
unless you've made a singular, personal commitment to a specific technology
stack. Leave yourself copious notes, Makefiles, and shell.nixes to remember
how to get the thing running! But this is a personal sob-story and a
digression.)

My main argument -- which I think is being lost here -- is that Ocaml isn't
IDE unfriendly, and especially not so unfriendly that an _entirely new
language_ is needed just so that FP and IDEs can happily coexist.

(Well, except for Windows. Ocaml + Windows is more unpleasant than it needs to
be.)

~~~
shallowthought
> My main argument -- which I think is being lost here -- is that Ocaml isn't
> IDE unfriendly, and especially not so unfriendly that an entirely new
> language is needed just so that FP and IDEs can happily coexist.

Right, and I guess my counterargument would be that, yes it is, and you don't
need to resort to logic to see it - just do a little googling about its poor
adoption.

------
tobr
Great to see the motivation spelled out clearly, but something seems strange.
If you read the Quora answer, it just rants about how functional programming
is obsessed with big words and esoteric concepts that are hard to grok, and
that this constitutes poor UX. But Keli’s interpretation seems to be that the
moment-to-moment experience in the IDE is poor, and that that’s what the
language wants to address with more explicit syntax and intellisense support.
These seem like two very different problems under the umbrella term “UX”.

------
pbiggar
I'm very sympathetic to the problem. I'm working on Dark
([https://darklang.com](https://darklang.com)) which is a functional language,
explicitly because we believe that functional languages are easier to learn,
understand and provide great tooling for.

It seems to me there's a lot of focus on syntax, and I don't think they've
gotten to a great place. For example:

    
    
      (this Int).square | Int = this.*(this)
    

In Rust, they do

    
    
      impl Int {
        fn square (self) -> Int {
          self * self
        }
      }
    

I can read the Keli version, but I'm note sure that `(this Int)`, `|`, and
`.*` are great inventions. You need a good reason to deviate from commonly
recognized syntax, and Keli doesn't feel like it's made things simpler with
this.

In Dark, we use piping heavily to get the benefits of the dot-syntax. In
particular, it can be type directed:

    
    
      8 |> Int::square |> Int::log 2
    

The autocomplete will only show you integer functions in this case.

For the problem of "which parameter" \- our IDE shows parameter names when
your cursor is in a position to type the next parameter, so you know what
you're adding it is. We also show the parameter names when your cursor is in
the completed argument so you know what parameter it is. (I couldn't see if
Keli did this, it might not be possible in modern editors).

------
ciuncan
I find the syntax as the author intended it to be: clean. I agree with the
ambiguity of positional parameters at first glance. Although named parameters
(e.g. in Scala) somewhat solve this, they are optional. Having the parameters
with their explicit name makes it quite readable.

    
    
      myList
          .append(5)
          .reverse
          .put(5) atIndex(0)
          .++(anotherList)
          .select(x | x.isEven)
    

Edit: The same feature makes it look a little weird when put on a single line,
because we mentally parse the whitespace as separator but in this case it is
not:

    
    
      $.name("Keli") age(50).isOld
    

It looks like a refreshing addition to function programming languages and I'd
like to see where it goes from here, in terms of adoption and features.

~~~
mst
$.name("Keli" :age 50).isOld

wold've been nicer to me but ah well.

~~~
lgessler
I can understand $.(:name "Keli" :age 50) but not $.name("Keli" :age 50), why
should the age bit go inside the parens? This introduces an asymmetry where
the first key appears outside parents and subsequent keys appear inside (and
as colon-initialed keywords?!)

------
beders
Unfortunately, no direct comparison to Lisps.

The two downsides mentioned regarding FP are not an issue if you are using a
REPL and a Lisp:

\- excellent IDE support, since you are working inside your program (which can
be inspected)

\- paradigm a la carte: you want named arguments? Go for it (split :string
"foo,bar" :by ",")

    
    
      you want different invocation syntax? (3 + 4) or (3 4 +) is just a macro away

and a bit easier to read than: (this Int).square | Int = this.*(this) YMMV

    
    
      you want to define your data shape? use your favorite schema language
    
      you want monads? just use a library
    
      you want go-routines? just use a library
    
      you want compile time types? just use a library

~~~
higerordermap
Except everything is brittle leaky abstraction.

------
maest
The following example is kinda funny:

    
    
        // This is obviously not too right
        ",".splitBy("1,2,3,4,5")
    
        // This should be right, because it reads out more naturally
        "1,2,3,4,5".splitBy(",")
    

Seeing as Python uses the first version for .join()

~~~
pmontra
Exactly what I came here to write about:

    
    
      Python 3.8.2 (default, Jul 16 2020, 14:00:26) 
      >>> " ".join(["a", "b"])
      'a b'
    

vs Ruby

    
    
      2.6.5 :001 > ["a", "b"].join(" ")
      => "a b" 
    

I don't know which one is more natural but I prefer the Ruby version because
it's consistent with

    
    
      "a b".split(" ")
    

which works in both languages. One less think to remember.

~~~
linkdd
In Python:

["a", "b"].join(" ")

This would mean the type list has a method join, how would it work with the
following ?

[1.5, "hello", None].join(" ")

~~~
rgoulter

      >>> " ".join([1.5, "hello", None])
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      TypeError: sequence item 0: expected string, float found
    

Why would `[1.5, "hello", None].join(" ")` be any different?

~~~
linkdd
Because "list of string" is not a type in Python.

Why would you put a method on a class if only a small subset of it can use it?

~~~
matt_kantor
Either way it's a partial function that is not defined for most of its domain.
The only difference is how its arguments (including self) get arranged at call
sites, right?

------
didibus
I'm not a fan of this:

'Hello world' replaceFromIndex: 0 toIndex: 4 with: 'Bye'

At first sight you might think, oh great don't even need to read the
documentation (which is the author argument in favour of this). But, is
"toIndex" inclusive or exclusive? Don't know, so now I need to read the
documentation anyways and just learn the behavior of the function. And once I
did, all those names just become visual noise that my eyes need to skip over
when reading and verbosity when writing.

Also, if you're going to go with this style, I'd much rather have function
first (as FP should):

replace in: 'Hello world' fromIndex: 0 toIndex: 4 with: 'Bye'

Which brings me to my second point, I prefer languages that just allow both.
Some functions are better positional and other named and some a mix of both.
Let each function choose the most appropriate one. For example, are we really
going to do this?

100 divide with: 5

or

divide theNumber: 100 with: 5

Ya, it reads like an explanation for a 5 year old, but as a professional
programmer I'd much rather:

divide 100 5

My point being, certain functions are intuitive even with positional args and
others arn't, only the latter should have named args.

Now for the intellisense section I agree, but I think you can solve it with
IDE UX. Like just provide a command that lists all locals for you to pick and
then lists all functions whose first argument is of that type. Or heck, have
it that after you type a var name, it lists functions over it but the list
shows to the left and when you pick it autocompletes the function text to the
left of it.

------
sfvisser
I really appreciate the effort of designing the syntax to match common IDE
expectations. However, I think it shouldn't be too difficult to add
intellisense for Haskell-like syntax to IDEs as well. Especially with all the
types available!

The only unconventional thing is that the function might be put in-front of
the value and some parentheses need to be added, instead of just putting it
after the cursor like with method syntax. I assume you get used to that rather
quickly.

~~~
dmitriid
> I think it shouldn't be too difficult to add intellisense for Haskell-like
> syntax to IDEs as well. Especially with all the types available!

On the contrary, this should give Haskell an advantage because all the types
are known and the IDE should be able to autocomplete only the correct
parameters. But that requires compiler-as-a-service, and GHC is not. And
writing your own analyser for a language is quite a task.

~~~
newen
Isn’t that why language server protocol is a thing?

~~~
dmitriid
Yup, kudos to MS for coming up with it and standardizing it.

(the following is just what I think, I have no hard knowledge on the matter)

Language server still limits what an IDE can do. E.g., IDEA can do complex
large scale refactoring and analysis over a codebase. If you're brave enough,
you can write your own language analyzer that converts your language into
structures IDEA understands, and you can get (some) of the same benefits. But
it's a lot of work.

IIRC, language server can only provide rather superficial type information and
autocompletion (which is still way more than many languages had before).

------
fouric
I feel like the named reasons, aside from being invalid (it should be really
really easy to make a popup that tells you the function parameter names and/or
types, like SLIME has been doing for...decades? with Common Lisp), are really
bad justifications for creating an _entirely new programming language_. Surely
the effort would be better spent on improving the tooling, because all of
their concerns are tooling-related.

That also makes the language not about a "good user experience" as given in
the docs, but "being compatible with modern IDEs". No thanks, I would rather
improve tooling for an existing language that already has a community and
ecosystem.

------
exclipy
Anyone else irked by the use of "Intellisense" \- a Microsoft brand - when
"autocomplete" will do?

~~~
52-6F-62
Seems like they're complaining (for lack of a better word) about only having
word autocomplete available for most functional languages versus a more
refined suggestion tool like Intellisense. But yeah, they don't get that
specific about that fact. I guess Intellisense has entered the realm of
Kleenex in how it's used.

~~~
Nullabillity
Mostly in .NET communities though, from what I've seen.

------
SZJX
I'm not sure those are the things holding FP back. The statement "The user
experiences of functional programming languages sucks." sounds really weird
and is the exact opposite of my experience. I write Elixir professionally. The
developer experience is unparalleled and I definitely wouldn't trade it for a
job writing Java 9 to 5.

Maybe it's trying to refer to stuffs such as existing libraries and package
management etc. when you want to quickly boot up a real-world project. I once
tried to write some web app in Haskell and that experience definitely was
anything but smooth. Fortunately Elixir has a really vibrant community and
libraries for the majority of common tasks (plus 20+ years of Erlang
ecosystem). It's also really easy to roll your own solutions.

I don't think the issues of IDE support and parameter ordering mentioned in
this article are problems to FP programmers at all. Powerful language servers
exist nowadays for all major functional languages and they're not that
different from language servers for OO languages. So yeah I tend to agree with
a lot of commentators that this article doesn't seem to make much sense
unfortunately.

------
crvdgc
Haskell Language Server ([https://github.com/haskell/haskell-language-
server](https://github.com/haskell/haskell-language-server)) offers a pretty
good IDE experience.

It also mitigates the parameter naming problem. With a type hole, the language
server will infer the type. But in the case of two parameters having the same
type, you have to consult the definition or doc.

------
centimeter
I disagree with all points in the article - the user experience with existing
FP languages is superior, and the IDE integration for strongly typed languages
is generally very impressive.

Syntactic window dressing isn’t what makes or breaks a language.

------
ollysb
While I could get onboard with functional languages being more user friendly I
didn't find the motivation to be compelling.

> Ambiguous functions argument positions

It just seems to be advocating for named arguments, something which the
majority of languages (OO or FP) support these days. You could say that
requiring named parameters is a feature but it's hard to get excited about.

> Not Intellisense friendly

I use Elm and Elixir, both of which have decent autocomplete in vscode (and I
believe many other editors).

Critique aside I definitely applaud more towards increasing FP adoption. I
think Elm has brought many good ideas to the table already (though admittedly
it's bias is more towards ideal than practical). On the flip side Elixir is
very pragmatic and easy to get going with for developers coming from OO
languages.

~~~
dnautics
Elixir is very good about function positions, too, by being consistent in it's
stdlib, and by pinning structs to modules. Almost all library writers adhere
to the convention.

~~~
dmitriid
People are also consistent because of the pipe operator which was there since
the very beginning. So everyone expects functions to work with chaining
correctly. That's why you get params that get changed a lot as the first
parameter etc.

------
theshetty
Why is no one talking much about Scala? ([https://docs.scala-
lang.org/overviews/scala-book/functional-...](https://docs.scala-
lang.org/overviews/scala-book/functional-programming.html))

~~~
pmarreck
Because we're trying to turn people _on_ to functional programming, not _off_

EDIT: Downvotes already? Look, Scala is NOT noob-friendly, and it's a rational
argument, not a preference. Here's an example: There are at least 10 (TEN)
different uses of the underscore character (_) in Scala. JFC. I can go on,
such as the proliferation of bizarre operators everywhere that are impossible
to Google (again, not noob-friendly), the reliance on JVM (ewww... so you end
up having to be a Scala expert AND a Java expert... plus deal with JVM windup
time and JVM stacktraces... Not noob-friendly), the consistent violation of
POLS, etc. etc.

~~~
the_af
> _and it 's a rational argument, not a preference_

It might have _some_ justification, but it's just your preference. Scala
gained a reputation of being a "difficult" language early on, I suppose mostly
by people coming from Java, and it has unfortunately stuck.

Singling out underscores in Scala as "difficult" is bizarre. There might be
many, but in practice it's very easy to understand what you want, and I've
never seen anyone seriously confused by them. What do you mean, "many bizarre
operators"? Are you using ScalaZ maybe?

What do you mean, JVM stacktraces are not newbie-friendly? They are a useful
tool to troubleshoot many problems. What problems do they have in your
opinion?

What's wrong with relying on the JVM?

Scala type signatures are sometimes hard to understand _in library code_. You
are not expected to write code like that unless you are writing general
purpose libraries, which you are likely not doing.

~~~
lgessler
> What's wrong with relying on the JVM?

It's that the user needs to learn not just Scala but also Java whenever they
want to do anything "real". You might say this is a minor hangup, but for
learners having to context switch back and forth between Java and Scala and
dealing with interop issues can make for much more cognitive load than using a
non-hosted language like Python or Go.

~~~
the_af
That Scala has a vast array of Java libraries is a strength, not a weakness.
Interop issues between Java and Scala are not a big deal, anyway. It's mostly
seamless.

------
SomeoneFromCA
I've almost misread it as "Keil", which brought bad recollections of their IDE
C/C++ IDE.

------
GrinningFool
Another way to solve the problem the author is looking to fix is by
convention:

    
    
        splitStringBy "1,2,3,4,5" "," 
         ^ action
              ^ Arg1
                   ^ Arg2

------
higerordermap
I am going to call bullshit on this:

1) Function argument order is not an issue in practice. Especially Elixir or
OCaml providing keyword arguments. Also, there are mostly conventions eg
search term comes first in replace function.

Elixir, F# all provide Pipes, while little more verbose than dot notation,
more universal than methods on objects.

2) IDE support: above points apply, although pervasive type inference may make
few things hard. It is best practice to annotate function signatures.

The real reasons why FP languages are unpopular are:

1\. immutability is often a bad abstraction and some FP languages often make
performance/memory reasoning harder[0].

2\. Your 9-5 engineer doesn't want to learn anything more than what they
learned in school or bootcamp.

3\. The impression created by some FP language communities. There are some
people always talking some complicated category theory stuff that's rarely
useful for programming, or propagating zero information statement like "If it
compiles it works". [1]

[0] "bUt ItS lIKe gRaDuAtE aBsTrAcT mAThEmAtICs it must be good and elegant
even if the machine doesn't work like this". Go and learn some real computer
science, algorithms, data structures, number theory, probability, instead of
touting your definitions of undergraduate logic and set theory.

[1] There is more chance it works, sure. But "If it compiles, it works" is
dishonest statements.

~~~
SZJX
Yeah I agree that those two points don't make much sense whatsoever. Though I
also don't agree with your point 1. I don't know if you have had much
experience writing a functional language professionally. The benefit of
immutability is exactly to make reasoning about your program _much easier_. Of
course as you mentioned computers are indeed based on the von Neumann model,
so in the end we sometimes have to go into memory usage details. However,
unless you're programming some high-performance game, the vast majority of
programs run totally fine with mostly immutable data structures. It's also
especially suited for distributed computing (e.g. actor model) which is
becoming the norm nowadays. In 95% of programming activities, the traditional
"real computer science (what is "fake" computer science?), algorithms, data
structures, number theory, probability" are used surprisingly rarely, while
the elegance of functional/mathematical reasoning really makes the programming
experience much more enjoyable and bug-free.

~~~
higerordermap
> In 95% of programming activities, the traditional "real computer science
> (what is "fake" computer science?), algorithms, data structures, number
> theory, probability" are used surprisingly rarely

Yeah, unfortunately, the cheap webshits use reverse loops because they read in
some medium article that comparison to zero is shorted, while repeatedly
concatenating strings in an inner loop.

Doesn't help with things like - indexing on utf-8 strings is O(n) and often
the compiler/JIT is not able to figure out all necessary loop fusions for you.

Basic algorithms, data structure knowledge is a must for every programmer. I
don't say they should know how to prove a treap is 0.yz times more efficient
than a skiplist. Now the next part.

> while the elegance of functional/mathematical reasoning ...

There is natural reasoning and there is category theory stuff that only serves
to signal the dude has studied some aBsTrAcT mAtHeMaTiCs in programming
communities.

A best example of this is Haskell. They bastatdized quicksort to show an
"elegant example" on their website.

Another example is react. "React is fast omg virtual DOM". Not everyone will
have latest macbook pro like hipster webshits.

I know, and I acknowledge the improvements in craft of ~~CRUD WEBSHIT~~
programming that came from FP camps. But there is also lot of bullshit there
in FP camps.

------
azhenley
There was some discussion on Reddit over a year ago that was interesting too:
[https://www.reddit.com/r/ProgrammingLanguages/comments/acrj9...](https://www.reddit.com/r/ProgrammingLanguages/comments/acrj9g/request_for_comments_on_my_new_language_keli/)

------
barrister
Can someone point out how Keli implements purity in the documentation? Haskell
_requires_ the IO monad to accomplish this, not sure what Keli does. Its
feature list claims to implement "pure functional programming" but it seems as
though it's just functional, like OCaml or F#.

------
stark3
On the AS400 there's a 'command' object type that deals with both issues the
Keli language is trying to address.

\- Argument positions are named, help text, validity checking, special values,
etc are defined for each argument.

\- Command arguments can be prompted within the editor (intellisense).

As400 commands can also be prompted and executed by a user, thus providing a
common user interface for running jobs as well.

I've seen nothing like this in the PC world. The two issues the Keli language
is trying to solve were addressed 30 years ago on the as400.

------
daxfohl
I like the idea but I think the tactics are wrong. The better approach would
try to make the experience as much like OOP as possible. Like the named
argument, message passing thing is nice, but it's going to be just one more
thing that the 95% is going to have to get used to. If the goal is
approachability, then have to get it as close to existing experiences as
possible.

------
leafboi
On the post it says Haskell is not IDE friendly. It is really hard to make an
IDE around Haskell or does it just that it lacks support?

~~~
whateveracct
It's just a matter of time investment imo. And with the current ghcide effort,
that's already happening!

The argument that you need method-style syntax to have good IDE support is
short-sighted. Haskell has something more powerful (typed holes), so a common
thought is Haskell needs a different sort of IDE support and not expect it to
feel the same as Java.

------
galaxyLogic
>However, OOP languages also suffers the same problem whenever the number of
function/method arguments get more than two, for example:

Well yes except Smalltalk, the original OOP-language. Smalltalk requires you
to use KEYWORD METHOD-NAMES whenever you have > 2 arguments. That makes
Smalltalk code highly readable.

(I told you so 20 years ago today) :-)

------
rishav_sharan
With every new upcoming language, I always have the same ask; Please add a
couple of section on what can we do with the language today.

Rust has amazing sites like arewegameyet or arewewebyet.

A single paragraph around what users can realistically do with this language
and what are the most used packages in the ecosystem will be a great help to
anyone curious about it.

~~~
spicybright
Wow, those sites are a really good idea. I wish tech was more honest with it's
pro's and con's. Seems like most project maintainers want to be marketers than
engineers sometimes...

------
_raz
If great IDE support and ux for developers is the goal wouldn't it be more
reasonable to spend the time on IDE support on existing FP languages rather
then creating a new one? It seems that Hindley-Milner type system of many
existing languages should lend it self well for language servers in general.
But what do i know

------
hannofcart
Firstly, kudos to the authors of Keli. Since the primer to the language begins
by examining what is preventing FP adoption, I'd like to add another key
reason: performance.

Haskell code can be optimised to run very fast indeed, but resulting optimised
code does not look much like idiomatic Haskell at all.

~~~
codygman
> Haskell code can be optimised to run very fast indeed, but resulting
> optimised code does not look much like idiomatic Haskell at all.

It's still Haskell though, which means it can compose nicely with all that
idiomatic Haskell!

Further I'd argue that you typically don't have to go to that level of
optimisation.

I'd be very confident in my above statement replacing node or Python REST apis
at least, but can imagine that not holding true in other domains.

In that case though, my first point still holds and I find that advantage very
powerful.

------
pmarreck
Elixir already solved that problem tho :)

------
hellofunk
We've built our SAAS on Keli for the last six years and have been amazed by
the productivity. Each year we are able to make a net reduction in lines of
code. We are now down to only 2 lines, and we expect next year to be the most
impressive yet for what we will need to maintain.

~~~
azhenley
Any chance you have a write up about your experience with it??

~~~
bboy13
I'm pretty sure this is a joke. There's no way you can run a SaaS on two lines
of code... Unless it's some bizzarely simple calculator or something like
that.

~~~
lostcolony
Of course it's a joke.

Sibling comments aside (without comment on my part), it would be hard to have
6 years of production use of a language that has its first git commit 2 years
ago.

------
ogre_codes
This seems like a dead project. It's fairly unknown and hasn't been updated in
over a year.

~~~
garmaine
Maybe they broke up?

~~~
hou32hou
No no we haven’t broke up yet

------
dvh
Noun verb. Haystack needle.

------
whateveracct
Wadler's Law at work

------
mmphosis
_reads out more naturally_

    
    
      set the delimiter to comma
      split 1,2,3,4,5
    

or

    
    
      split 1,2,3,4,5 by comma

------
shaunxcode
I got excited at the idea of smalltalk syntax in functional clothing but it
never seemed to deliver?

~~~
hou32hou
It won’t be delivered because it’s actually my final year project for my
software engineering degree, and plus I’m also not convinced by this language
anymore, I still think that there’s a better syntax which I can’t think of
right now

~~~
shaunxcode
Keep going!

------
jayp1418
Is this being developed? How similar this is to ada ?

~~~
throwaway43234
Hasn't been touched in over a year.
[https://github.com/KeliLanguage](https://github.com/KeliLanguage)

~~~
cridenour
Maybe they broke up.

------
adultSwim
The F# IDE is really good actually

------
gdsdfe
another terrible programming language website ...

------
yters
i do not agree with the implief premise that functional programming is not
inherently the act of joy itself

------
endergen
Off serious topic: Naming it after you girlfriend is a risky move, like
getting a tattoo of her. Better get married and stay that way or the next
partner is gonna be like: "wtf", you still working on your tribute to your ex
programming language!?

~~~
didip
This isn't too bad. We live in Git society now.

After the breakup, fork, rename to the new girlfriend name, and put a notice
on README.md:

"I broke up with Keli but don't worry, I am with Sandra now. Please follow the
new language <a
href="[https://sandralang.org">here</a>"](https://sandralang.org">here</a>")

~~~
asdfman123
Relationships are just like new technologies. Sick of all all the hassle you
have to deal with regarding <existing technology>? Use a new, shiny
technology!

 _Five years later..._

Sick of all the hassle you have to deal with regarding <formerly new
technology>...?

The lesson here is ultimately all technologies suck, but you have to find the
variety of suck you're willing to live with.

~~~
comboy
> The lesson here is ultimately all technologies suck, but you have to find
> the variety of suck you're willing to live with.

Alternative view is that they all have their uses and if you choose the right
one for the use case, it makes your life easier, not harder, especially once
you get to know it well.

It helps if you know what do you want. Not a single one is good at everything.

~~~
asdfman123
Shop shooting holes through lingering post-adolescent cynicism!

------
gridlockd
If I want to do functional programming, I can do that just fine in most
languages.

If I want to do imperative programming, I can do that just fine in most
languages, _except for functional programming languages_.

~~~
spicybright
I think the key with a functional language is given a large codebase, you can
reason about it functionally instead of hoping there's no imperative code in
there (on purpose or by bug)

~~~
gridlockd
Kind of like if you're wearing a straitjacket, you don't need to worry about
accidentally punching yourself in the face.

