[HN Gopher] Keli: A programming language to make Functional Prog...
       ___________________________________________________________________
        
       Keli: A programming language to make Functional Programming a joy
       for users
        
       Author : azhenley
       Score  : 238 points
       Date   : 2020-08-31 14:14 UTC (8 hours ago)
        
 (HTM) web link (keli-language.gitbook.io)
 (TXT) w3m dump (keli-language.gitbook.io)
        
       | fsloth wrote:
       | 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.
        
         | jlturner wrote:
         | I second this. F# is quite IDE friendly, and auto completion
         | works great. Additionally much of the .NET tooling (with the
         | exception of C# specific refactoring tools) are CIL / bytecode
         | level and independent of CLR language. This is one of the
         | reasons having a polyglot solution of C# and F# projects is
         | possible and with (mostly) seamless interop - all the same
         | bytecode in the end.
        
         | pjmlp wrote:
         | 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.
        
           | jayd16 wrote:
           | I'm told F# is where the toys come from.
        
           | skolsuper wrote:
           | I think you mean black sheep
        
           | [deleted]
        
           | fsloth wrote:
           | 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 wrote:
             | 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 wrote:
               | 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.
        
         | O_H_E wrote:
         | They also admit that it is better than average here:
         | https://keli-language.gitbook.io/doc/specification/chapter-1...
         | 
         | > Keli is created to overcome a problem that is almost
         | undeniable in every functional programming languages: the lack
         | of proper IDE incorporation (perhaps except F#). In short, Keli
         | can be viewed as an attempt to assimilate the Smalltalk's
         | syntactic model into a functional programming environment.
        
       | beders wrote:
       | 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
        
       | [deleted]
        
       | ciuncan wrote:
       | 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 wrote:
         | $.name("Keli" :age 50).isOld
         | 
         | wold've been nicer to me but ah well.
        
           | ogre_codes wrote:
           | I agree, having age(50) separate almost looks like a separate
           | function call.
        
           | lgessler wrote:
           | 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?!)
        
       | gdsdfe wrote:
       | another terrible programming language website ...
        
       | theshetty wrote:
       | Why is no one talking much about Scala? (https://docs.scala-
       | lang.org/overviews/scala-book/functional-...)
        
         | MrPowers wrote:
         | Scala is unfortunately famous for having a toxic community as
         | well. I've emailed with most of the "famous open source" Scala
         | folks and they've all been really nice. But the subreddit seems
         | to have some nasty folks, especially compared with other
         | communities I've been involved with. It's a shame. It's a great
         | language and the people producing the popular libraries are
         | nice.
        
         | pmarreck wrote:
         | 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.
        
           | smabie wrote:
           | The dominant OO+FP paradigm of Scala code is one of the most
           | powerful, imo. Combining immutable objects with FP constructs
           | is my favorite way of programming and something that only
           | Scala can really do (well OCaml can, but no one uses
           | objects).
           | 
           | Scala is probably the most flexible and powerful statically
           | typed language currently in widespread use and I would
           | probably choose the language for most non-scientific
           | computing greenfield projects.
           | 
           | In my experience of on boarding developers who didn't know
           | Scala or Java into a large Scala project, it's really not
           | that hard to learn. Developers were writing okay code in the
           | first week and completely idiomatic code after the first
           | couple weeks.
           | 
           | The JVM does suffer from non-transparent performance
           | characteristics, but the highly optimized and tested platform
           | makes up for it.
           | 
           | Scala the language is getting better and better and Scala 3
           | will really be something special, I think.
           | 
           | The worst part of the JVM is dependency management. Upgrading
           | the version of Scala you're using is unbelievably painful and
           | in a lot of cases impossible.
           | 
           | My old Scala shop is still running on 2.10 because no ones
           | bothered to put in the weeks of work to upgrade.
        
           | adav wrote:
           | Nothing's noob-friendly if you begin with advanced features.
           | 
           | Scala is eminently beginner friendly when introduced to
           | developers familiar with OOP. This approach was how I first
           | experienced Scala and it ended up becoming a gateway drug
           | into FP proper.
           | 
           | Regarding underscores in Scala, yes there are many technical
           | terms for each thing it has the capability of representing...
           | but in reality, you just use it wherever you want to ignore a
           | value with a placeholder or pass a provided value through.
        
             | MrPowers wrote:
             | I learned Scala a few years ago and have some popular open
             | source Scala libs. I like Scala, but wouldn't call it
             | "eminently beginner friendly". Coming from Ruby, it was
             | hard for me to learn SBT, Maven, Scalatest (much more
             | complicated than Gemfiles, rubygems, and rspec in my
             | opinion). With Ruby, you can easily make an Array.
             | 
             | Scala newbies find it hard to even perform basic Array
             | operations. You need to dig into Array, Seq, and List,
             | figure out the differences, try to see what's accepted by
             | the community, etc.
        
           | the_af wrote:
           | > _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 wrote:
             | > 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.
        
           | haggy wrote:
           | When is the last time you used it? I've been a full time
           | scala developer for over 4 years now spanning versions 2.11,
           | 2.12, and now heading into 2.13. There have been massive
           | improvements across consistency and huge convergences
           | happening across the scala FP community in terms of library
           | usage.
           | 
           | > 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)
           | 
           | This is just plain weird. This makes me feel like you spent
           | zero time actually working with the JVM and it's incredible
           | ecosystem. Being fully inter-operable with Java is a huge win
           | for both adoption and usability. Not only that but the JVM is
           | one of the most mature runtimes in existence with massive
           | amounts of documentation and help available.
        
           | non-entity wrote:
           | Honestly some of the reasons I stay away from learning Scala
           | are the same one that keep me from learning C++
        
       | yters wrote:
       | i do not agree with the implief premise that functional
       | programming is not inherently the act of joy itself
        
       | maest wrote:
       | 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()
        
         | thefifthsetpin wrote:
         | If I were designing a functional language, I'd be thinking
         | about whether data.splitBy or delimiter.split was useful even
         | when not immediately invoked.
         | 
         | Consider this crude csv parser:
         | 
         | using splitBy:
         | csv.splitBy("\n").map(csv_row=>csv_row.splitBy(","))
         | 
         | using split:                   "\n".split(csv).map(",".split)
         | 
         | split was the clear winner here. Given splitBy, I basically
         | recreated split as a lambda.
         | 
         | I tried to create an analog to that where splitBy would come
         | out looking better. I figured that if we didn't know the
         | dimensionality of our data, then delimiters becomes an array of
         | arbitrary length and we could pass data.!splitBy into something
         | like delimiters.reduce. When actually writing that, however, I
         | wound up recreating split again:
         | 
         | using splitBy:                   delimiters.reduce((accum,delim
         | )=>accum.deepMap(data=>data.splitBy(delim)),[data])
         | 
         | using split:                   delimiters.reduce((accum,delim)=
         | >accum.deepMap(delim.split),[data])
        
         | IshKebab wrote:
         | Yeah Python (and I think JavaScript?) pretty clearly have
         | `join` backwards.
        
           | b34r wrote:
           | JS uses the second example
        
             | linkdd wrote:
             | It is because in Javascript everything can be translated to
             | a string:
             | 
             | 1 + "hello" == "1hello"
             | 
             | Therefore, the type Array can have a join method that have
             | predictable results (unlike Python).
        
               | Zarel wrote:
               | I don't know what that has to do with `join`'s call
               | order.
               | 
               | As mentioned above, it's because Python supports `join`
               | on any sequence, not just the array class. Personally, I
               | find JavaScript's solution neater:
               | [..."hello"].join(" ") === "h e l l o"
        
               | linkdd wrote:
               | Because when the Javascript engine will try to
               | concatenate all the strings in the Array (the expected
               | behavior of join), it will first translate every object
               | in the array to a string.
               | 
               | Javascript always falls back to string, that is also why
               | we have === and == operators.
               | 
               | Python's type system is a bit more strict because it will
               | not attempt to serialize your objet if you haven't
               | explicitly done it yourself.
               | 
               | My point is: Python doesn't use this notation because it
               | would not make sense in Python.
        
               | maest wrote:
               | This is also the cause of this lovely bit of JS
               | behaviour:                   >>> [1,2,10].sort()
               | Array(3) [ 1, 10, 2 ]
        
         | pmontra wrote:
         | 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 wrote:
           | 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(" ")
        
             | pmontra wrote:
             | Principle of least surprise: make it work like
             | >>> f"{1.5} {'hello'} {None}"       '1.5 hello None'
             | 
             | Ruby does that. From [1] "[Array#join] Returns a string
             | created by converting each element of the array to a
             | string, separated by the given separator."
             | 
             | The difference is that nil (Ruby's None) disappears
             | 2.6.5 :001 > [1.5, "hello", nil].join(" ")        => "1.5
             | hello "
             | 
             | That's totally expected because in Ruby the conversion of
             | nil into a string is the empty string. Python converts it
             | into the string "None".
             | 
             | [1] https://ruby-doc.org/core-2.6.5/Array.html#method-i-
             | join
             | 
             | Edit: an example with a type that normally wouldn't
             | meaningfully cast to string                 2.6.5 :001 >
             | class Example       2.6.5 :002?>   attr_accessor :name
             | 2.6.5 :003?> end        => nil        2.6.5 :004 > e =
             | Example.new        => #<Example:0x000055a321fa2bb0>
             | 2.6.5 :005 > e.name = "example"        => "example"
             | 2.6.5 :006 > e.to_s        =>
             | "#<Example:0x000055a321fa2bb0>"        2.6.5 :007 > [1,
             | e].join(" ")        => "1 #<Example:0x000055a321fa2bb0>"
             | 2.6.5 :008 > class Example       2.6.5 :009?>
             | attr_accessor :name       2.6.5 :010?>   def to_s
             | 2.6.5 :011?>     "#{name}"       2.6.5 :012?>   end
             | 2.6.5 :013?> end        => :to_s        2.6.5 :014 > e =
             | Example.new        => #<Example:0x000055a321f8a4c0>
             | 2.6.5 :015 > e.name = "example"        => "example"
             | 2.6.5 :016 > e.to_s        => "example"        2.6.5 :017 >
             | [1, e].join(" ")        => "1 example"
        
             | rgoulter wrote:
             | >>> " ".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 wrote:
               | 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?
        
               | Mathnerd314 wrote:
               | That happens all the time, since Python is dynamically
               | typed. For example a[10] gives an IndexError if a has
               | less than 11 elements. So with static typing, we should
               | restrict indexing to ensure that the number of elements
               | needed are present, and remove indexing from general
               | lists. But you wouldn't remove indexing from lists,
               | that's one of the main functions...
        
               | matt_kantor wrote:
               | 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?
        
           | zem wrote:
           | the key difference is that in ruby, `join` is implemented in
           | the `Enumerable` mixin (which provides a whole suite of
           | functionality to any object with an `each` method). if your
           | own class wants to support `join`, it has to both implement
           | `each` and explicitly mix in `Enumerable`.
           | 
           | in python, `join` is implemented in the `string` class, and
           | the _argument_ is an iterable. therefore, if your class wants
           | to support `join`, it needs to implement the `__iter__`
           | method (python 's equivalent of ruby's `each`), but it does
           | not need to also mix in an implementation of `join`.
           | 
           | it's mostly a cultural difference between ruby and python -
           | the ruby ecosystem leans more heavily towards mixins and
           | implementing generic functionality by attaching methods to
           | objects, whereas the python ecosystem leans more heavily
           | towards implementing generic functionality by providing
           | functions (or methods on an external class) that accept
           | generic objects.
        
             | pmontra wrote:
             | Actually join is a method of Array https://ruby-
             | doc.org/core-2.6.5/Array.html
             | 
             | A class that wants to support join has to implement to_s.
             | The definition of join is
             | 
             | > join(separator=$,) - str
             | 
             | > Returns a string created by converting each element of
             | the array to a string, separated by the given separator. If
             | the separator is nil, it uses current $,. If both the
             | separator and $, are nil, it uses an empty string.
             | 
             | If the class doesn't implement to_s Object.to_s kicks in
             | and displays something like
             | "#<SomeClass:0x000055a321fa2bb0>"
             | 
             | Enumerable is really a mixin https://ruby-
             | doc.org/core-2.6.5/Enumerable.html but join is not listed
             | in its methods.
             | 
             | There is another reply of mine with an example of a class
             | can be used in join and doesn't mix in Enumerable.
        
               | zem wrote:
               | oops, right you are, it's not defined on Enumerable
               | (though i do wonder why! `each` does define an iteration
               | order after all)
        
       | hannofcart wrote:
       | 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.
        
       | [deleted]
        
       | rubyist5eva wrote:
       | You can achieve this style with Ruby and keyword arguments, no
       | new language required.
        
         | identity0 wrote:
         | And you can emulate most of C++ in C with macros. Doesn't mean
         | you should.
        
           | rubyist5eva wrote:
           | false equivalence, there is no "emulation" of features they
           | are native to the language
        
       | pmarreck wrote:
       | Elixir already solved that problem tho :)
        
       | enricozb wrote:
       | 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.
        
         | nybble41 wrote:
         | This particular set of examples is especially ambiguous because
         | "splitBy" can be read two different ways: as a description of
         | the result ( _noun_ having been split by a separator) or as an
         | action ( _subject_ split _direct object_ by a separator). Which
         | one you choose will subtly affect the way you group the
         | arguments. Conventions in functional programming tend to prefer
         | the former, whereas imperative (including OOP) languages prefer
         | the latter. Either way, however, the string which directly
         | follows `splitBy` should be the separator. In the functional
         | example:                   -- Is this correct?         splitBy
         | ","  "1,2,3,4,5"              -- or this?         splitBy
         | "1,2,3,4,5"  ","
         | 
         | there really is no question that the first version is correct.
         | Even oversimplifying as the article does and treating "basic
         | English" as the only applicable domain knowledge, I'm not
         | likely to read "split by ',' ..." as an instruction to split
         | the string "," by some other separator. To understand how the
         | second string fits in you need more than basic English, because
         | English doesn't have that sort of syntax. However, once you
         | learn that it parses as `(splitBy ",") "1,2,3,4,5"` the result
         | is pretty obvious.
         | 
         | In the OOP language example the second version with the string
         | knowing how to split itself, as it were, does make more sense
         | than the first version. The target of the method is always the
         | subject, and the method name is usually read as a verb, with
         | parameters as direct or indirect objects. (Read as: String
         | "1,2,3,4,5" (S), split yourself (V) by the string "," (I.O.).)
         | However, in functional programming the bias is exactly the
         | opposite, because _functional_ programming is about programming
         | with first-class _functions_ on _data_ , not performing
         | actions. You could easily arrange to write:
         | "1,2,3,4,5" `splitBy` ","
         | 
         | in Haskell using infix notation, and it even reads fairly well
         | reinterpreted as English prose. However, defining `splitBy`
         | this way would imply the curried prefix version:
         | splitBy ","
         | 
         | would not be a function that splits its input by ",", as one
         | would expect, but rather one that splits "," by its input.
         | Which just goes to show that not every function is well suited
         | for both infix and prefix notation. Whichever version you
         | choose needs to be used consistently. In general the convention
         | has been to define multi-parameter functions such that they can
         | easily be used as combinators, via currying, which seems
         | fitting to me given the nature of functional programming.
         | Functions which are designed to read well as infix operators
         | usually require operator sections or `flip` to adapt them for
         | use as combinators.
         | 
         | > I think, in general, requiring named arguments is a good
         | thing.
         | 
         | I have no objection to _optional_ named parameters, but making
         | them _required_ would necessarily eliminate currying and simple
         | function composition, and _that_ I have a problem with. Record
         | parameters with named fields are generally sufficient for the
         | situations where named parameters are useful, especially since
         | they 're ordinary data which you can manipulate at will and not
         | some special syntax baked into the language just for function
         | calls.
        
         | drdebug wrote:
         | The question is should the writer go through the effort of
         | placing the parameter name, or should the reader go through the
         | effort of looking up the function prototype? Since according to
         | Clean Code (https://www.goodreads.com/quotes/835238-indeed-the-
         | ratio-of-...) code is more often read than written, it should
         | makes sense for the writer to do it.
        
         | laumars wrote:
         | 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).
        
           | enricozb wrote:
           | They are biased to new readers of a codebase, not of a
           | language, which is really just another way of saying that the
           | code is very readable.
        
             | laumars wrote:
             | I don't think it's fair to say what's readable to new
             | developers is the same as what's readable to experienced
             | developers nor even every developer.
             | 
             | For example the terse style of Sexpressions or C-style
             | braces are off putting to some but after a short while they
             | become second nature to visually parse (not saying all code
             | should follow Those idioms, just using that as an example
             | of how readability changes with experience). On the other
             | hand I never found it as straightforward visually parsing
             | the "word soup" of named arguments when using languages
             | that favoured it. While those languages were easier to
             | learn the basics, they quickly became tiresome to write
             | larger code bases with.
             | 
             | But I guess this just boils down to personal preference.
        
               | enricozb wrote:
               | I'm talking specifically about the function calls, which
               | are effectively the same in C, Rust, Python, Lisp,
               | Haskell, and many others. No matter how terse, it's
               | always some form of
               | 
               | <name of function> <value1> <value2> <value3> ...
               | 
               | The absence/presence of parenthesis and commas don't add
               | anything of semantic value here, so that's not really
               | what I'm referring to.
               | 
               | The problem is, is that the values often don't have any
               | meaning attached to them, especially when they are
               | literals. C++ codebases are pretty bad about this with
               | boolean parameters, just having a random `true` at the
               | end of the function call.
               | 
               | Variable names at the call-site are good hints, but we
               | often pass the same variable to different functions, and
               | the name doesn't exactly fit the meaning of each
               | function. This is why I think requiring named parameters,
               | at least by default, is better.
        
               | laumars wrote:
               | I agree random boolean arguments are unhelpful. Good
               | software development standards would say any uses of
               | boolean values should be substituted with well named
               | constants if the same value. However the advantage of
               | having that baked into the language rather than forcing
               | developers to via code reviews isn't lost on me
        
           | cellularmitosis wrote:
           | Advocating for trading away readability in favor of easing
           | the lives of devs who refuse to use an IDE doesn't seem like
           | a win, especially in the context of a team.
        
             | laumars wrote:
             | I'm often writing code into vim (without any fancy plugins
             | installed) and never had an issue. As I stated in my
             | previous comment, I don't particularly believe named
             | arguments make it any easier to write without an IDE
             | because you're only trading memorising the order of
             | parameters with the names of those parameters. Either way
             | there's still a minimum level of memorisation required.
             | 
             | I get each developer is different but personally I remember
             | numbers and orders easier than names.
             | 
             | And frankly, if you have a developer who can't learn the
             | basics of the language they're employed to work on yet also
             | refuses to use any developer-friendly tools to assist him,
             | then that's a failing of the the developer and not the
             | language.
        
           | boxed wrote:
           | I disagree 100%. I write with more and more named arguments.
           | There are missing features to make it really nice in python
           | though, like kwarg short forms like ocaml has.
        
           | Kuinox wrote:
           | They are biased towards new users of a codebase, not only the
           | language.
           | 
           | Named arguments improve readability of a code if you are not
           | used to a codebase. By improving readability, you also
           | improve maintanability: you need less experience in a
           | codebase to make a change.
           | 
           | You focus on writability where it's not the biggest issue of
           | the field, it's software debt.
        
           | WillPostForFood wrote:
           | >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?
        
             | erezsh wrote:
             | Unlike positional arguments? ...
        
             | pmarreck wrote:
             | I haven't used an IDE in years. Just VSCode. Which is not
             | really an IDE. I haven't missed it. I think that if a
             | language depends on an IDE to be useful, it's a design
             | smell.
        
               | rightbyte wrote:
               | VSCode is an IDE. Otherwise, what is am IDE according to
               | you? Is Emacs an IDE? Eclispe?
        
               | eitland wrote:
               | VS Code (which I like and have used extensively for a
               | number of projects) is kind of an IDE, but it doesn't
               | quite compare to full blown Java IDEs IMO.
        
               | Joker_vD wrote:
               | It's an editor with syntax highlighter, autocompletion,
               | go-to-def, and go-to-uses that also builds the code, runs
               | the code, runs the tests, and also allows you to run them
               | (code & tests) under a debugger. Oh, and it also has
               | projects/solutions/workspaces/whatever they're called.
               | 
               | Back in my days(tm) that's what they used to call an
               | "IDE". But today that's just "glorified Notepad++", I
               | guess? What features does it miss that stop it being a
               | full-blown IDE?
        
               | eitland wrote:
               | I wrote kind of like an IDE :-)
               | 
               | Maybe I'm just a spoiled brat, but I came to Java from C,
               | PHP, Visual Studio (the old one) and learned how nice
               | programming could be before I left for .Net Core and
               | frontend (with much TypeScript), mostly in VS Code but
               | sometimes in Rider and Webstorm.
               | 
               | To me, to be a real IDE these days you need to have
               | proper refactoring support.
               | 
               | And to a spoiled brat like me that excludes almost
               | everything except Rider, Visual Studio with Resharper,
               | NetBeans, Eclipse and IntelliJ :-)
               | 
               | But yes, I too am old enough to remember back when the
               | C/Assembler program we used to program microcontrollers
               | were considered IDEs.
               | 
               | And technically you are of course correct :-)
               | 
               | I guess a better classification would be: IDE level
               | 1,2,...n where what I call IDEs today are really level 3
               | IDEs.
        
             | lostcolony wrote:
             | 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.
        
           | ogre_codes wrote:
           | Disagree. Particularly since named arguments are part of the
           | function name and in languages where you use named arguments
           | you will often have very expressive overloaded function
           | names.
           | 
           | You might have 3 related functions like so:
           | getStudent(datastore: DS, byId: number)
           | getStudent(datastore: DS, byAssessmentId: number)
           | getStudent(datastore: DS, firstName: string, lastName:
           | string, birthdate: date)
           | 
           | Without named parameters, you are stuck with function names
           | like: getStudentById, or relying on convention for naming
           | parameters and often wind up with duplicate names or not
           | knowing if a function is out there because your idea of
           | naming is different from someone else's.
           | 
           | Intellisense picks this up too and suggests the 3 different
           | names. Works fantastic.
        
             | laumars wrote:
             | I get overloading is a popular way of writing DRY code but
             | I've never been a fan of overloading either. You might
             | dislike getSomethingBySomething style function names but
             | it's no different to the examples you've given in terms of
             | readability but with the bonus of having fewer surprises.
        
               | ogre_codes wrote:
               | Should I look for the function called:
               | `getStudentByClassRoomFirstNameLastName` or is it
               | `getStudentByClassRoomLastNameFirstName`, or
               | `getStudentByClassRoomFullName` since you sort that way.
               | They you have to deal with optional parameters, do you
               | have an extra argument for that or is there a
               | `getStudentByClassRoomFirstNameLastNameMiddleName`
               | function out there? Now you are scanning the auto-
               | complete code trying to figure out which function you
               | need to call.
               | 
               | If you have named parameters, this just works:
               | `getStudent(classRoom: 15, firstName: "Mary", lastName:
               | "Jane")`       `getStudent(classRoom: 15, firstName:
               | "Mary", lastName: "Jane", middle: "Anne")`
               | 
               | It can call the same function with optional parameters,
               | or 2 different functions and you don't care from the
               | calling side because the syntax is the same and always
               | makes sense.
               | 
               | (slight tangent)
               | 
               | Far better with overloading in general is being able to
               | have 2 methods with the same name which return the same
               | thing but have different types of inputs. Like in Elixir,
               | you can have an API callback be `handle(apiResult)`, then
               | have 2 functions, one which handles the error and one
               | which handles the success. Zero logic written to filter
               | out bad-calls, it's just the same method with different
               | types (the Error result type and the Success result
               | type). Vastly simplifies and cleans up that kind of code.
        
               | dmitriid wrote:
               | Even better is Elixir's Ecto or Linq
               | Students |> Students.Repo.get_by(first_name: "Ryan")
               | from s in Students where firstName = "X" select s
               | Students.AsEnumerable().Select(s => s).Where(s => s.Name
               | == "X")
               | 
               | etc.
        
               | ogre_codes wrote:
               | Elixir is what I was thinking of for much of the above,
               | unfortunately, I only used it fairly briefly and so I was
               | going largely on memory and some of that is likely more
               | Swift than Elixir which shares some of that.
               | 
               | I really loved using Elixir, very frustrating going back
               | to TypeScript after that.
        
             | kingdomcome50 wrote:
             | I'm honestly curious what you see as the issue with
             | "getStudentBy"-type function names. Could you expand on
             | that?
             | 
             | Of course I understand a name could become rather verbose
             | in your last case, but I'm not satisfied that it would be
             | much of an issue in practice.
        
               | ogre_codes wrote:
               | See above.
        
               | kingdomcome50 wrote:
               | Hmmm... I see where you are going there, but I don't
               | understand how named arguments solve the problem[0] you
               | have outlined. That is, a problem of discoverability.
               | 
               | Like what, precisely, does the autocomplete show in your
               | editor when you type `getStudent` vs `getStudentBy` that
               | makes the former so much better? In either case you are
               | left to disambiguate either the correct overload or the
               | correct method unless... well... you already know there
               | is an overload that accepts the data you happen to be
               | working with. Presumably you would also then know the
               | correct method name.
               | 
               | I suppose it's possible to start typing your named
               | parameters directly and the editor "fills in" name you
               | are going for? But that poses nearly the same problem
               | again: "Wait... is it 'nationality' or 'country'? Did we
               | decide on 'lastname' or 'surname'?"
               | 
               | I agree the `getStudentByCountryAndName` isn't a great
               | signature, and that wrapping all of the args into a
               | single DTO like `StudentInfo` is not so great either. But
               | I can honestly say, I have _never_ once run into a
               | problem of _finding_ a method in the wild! Even if we had
               | numerous `getStudentBy`-type functions all with similar
               | signatures /names it probably wouldn't take more than a
               | few seconds to narrow down to the one of interest.
               | 
               | I also find, from a consumer perspective, named-
               | parameters to be _less_ ergonomic. I like that when I
               | type `getStudentById(` my editor boldens the argument I
               | am meant to pass next. I don 't have to _decide_ which
               | parameter I am going to pass next... my editor just
               | _walks me_ through the function (maybe I 'm just lazy!)
               | 
               | To be clear, I am not arguing against named-parameters.
               | Though I dislike that they broaden the public surface of
               | functions, I suppose I would rather at least have the
               | option to use them than not at all. I just don't really
               | see, in a practical sense, how they would improve a code-
               | base beyond some fairly niche scenarios that are probably
               | a code smell anyway.
               | 
               | [0] It seems to me your argument is more aimed towards
               | overloading than named-parameters in particular, but I
               | will accept that there is significant overlap in this
               | space.
        
           | gotostatement wrote:
           | maybe named parameters only for functions with more than 2
           | arguments might be a good compromise?
        
           | agentultra wrote:
           | How would function composition work without currying? You'd
           | have to name everything, wouldn't you?
           | 
           | I'm thinking of how you could write in point-free style or
           | even have a `(.)` function to begin with if you had the
           | Smalltalk "message passing" style.
           | 
           | Sure the Haskell syntax is a bit much when you're not
           | familiar with it but, like almost any language, it's often
           | the least-interesting part of the language and the most
           | talked about.
        
             | djhaskin987 wrote:
             | That's the whole point of the syntax changes: to make the
             | tradeoff that sacrifices terseness or efficiency or even
             | composability in favor of readability.
             | 
             | A lot of functional languages -- Haskell as I understand it
             | is the biggest perpetrator -- optimize for code length and
             | composability, trying to make things as expressive as
             | possible, and decrying those who can't read something that
             | has meaning densely packed into every single character as
             | those who are "simply not familiar" with the language.
             | 
             | But that's what OP is saying: OO languages go for
             | readability and not expressiveness, and wouldn't it be cool
             | if there was an FP language that did the same thing?
        
               | smabie wrote:
               | After learning some array languages, functional languages
               | like Haskell are actually pretty verbose.
               | 
               | Moreover, I believe that in general, shorter code is more
               | readable code. People just like to make excuses in order
               | to avoid learning anything new.
        
               | agentultra wrote:
               | I feel like that's a value statement and how you qualify
               | _readability_ would change the answer.
               | 
               | I'm curious if Keli plans to maintain function
               | composition in the face of named arguments. It would be
               | quite nice to have both.
        
           | m12k wrote:
           | I disagree that named parameters are just biased toward new
           | users. They're also biased toward reading rather than
           | writing. I find that as a code base becomes bigger and more
           | non-trivial, I end up reading code many times, and the more I
           | appreciate named parameters.
        
             | didibus wrote:
             | For a language that says it'll work hard to be IDE
             | friendly, an IDE can easily show you the argument names and
             | their order for any function. On IntelliJ, it even overlay
             | them.
             | 
             | Thus, you can be writer friendly and reader friendly,
             | considering the reader uses an IDE.
        
               | Jaxan wrote:
               | But why not turn this around? Let the IDE autocomplete
               | everything, so it's easy for the writer (or even hide the
               | named arguments). And have the named arguments in the
               | source code, then all readers can read it no matter their
               | IDE!
        
               | mattmanser wrote:
               | Because it's a pain to navigate with the keyboard, plus
               | accidental completion means more deleting, and other
               | little niggles like that.
        
             | implicit wrote:
             | I understand what you're saying, but something I have
             | noticed over the years is that the amount of code that I
             | can make sense of at any given time is actually
             | proportional to what I can see onscreen at any given
             | moment.
             | 
             | I have had pretty good luck cheating this in a bunch of
             | ways: I use a small font, a big display, and I use a terse
             | programming style.
             | 
             | Once you internalize a bunch of common higher-order
             | functions, you learn how to draw a ton of meaning out of a
             | relatively small number of terms.
        
               | DonaldPShimoda wrote:
               | Yes, but this strategy is only suitable for a single
               | developer, or a small group of similarly-experienced-
               | with-that-specific-codebase developers. Onboarding
               | somebody into a world full of single-character variable
               | names and such is a headache. Named parameters are for
               | reading code, and if you're not intimately familiar with
               | the code on your screen right this second, they are
               | helpful.
               | 
               | I think what we really need is a sort of "lens" system by
               | which we can modify the syntactic appearance of our code
               | without adjusting the semantics, but do these changes on-
               | the-fly. So say you're doing some debugging or whatever
               | and you're gonna be staring at the same 300 lines of code
               | for a few days -- so you switch over to "terse" mode and
               | suddenly the named parameters are gone and the variable
               | names are abbreviated (assume a magic system that picks
               | good terse variable names according to your preference).
               | But then when you're done with that section and ready to
               | venture into the remainder of the codebase (or if you're
               | a new developer who's unused to the team's naming
               | conventions or whatever), you can use "verbose" mode that
               | shows the parameter names and whatnot.
               | 
               | I imagine something like this is not obviously
               | straightforward, but it could be worth investigating!
        
               | laumars wrote:
               | > _Onboarding somebody into a world full of single-
               | character variable names and such is a headache._
               | 
               | The opposite of named arguments isn't single character
               | variable names. Any organisation with an enforced coding
               | standard would ensure that variables are descriptive
               | irrespective of whether that language uses named
               | arguments or not.
        
               | DonaldPShimoda wrote:
               | Yes, I agree! I was specifically addressing the parent
               | comment's line about "I use a terse programming style."
               | When it comes to functional programmers, they (more than
               | any other group) will take terseness to the extreme in
               | the form of single-letter variable names in inner
               | functions, match forms, etc.
               | 
               | I didn't mean for my comment to be entirely literal,
               | either. Rather, I just meant to say that terseness can
               | _impede_ readability for those who are not yet familiar
               | with the codebase. (But I have personally been on the
               | receiving end of onboarding into a codebase full of
               | literal single-character names, which I found incredibly
               | frustrating.)
        
               | implicit wrote:
               | The right balance here can depend on the specific
               | business you're working in.
               | 
               | Some companies earn the privilege of a super tenured core
               | team of engineers who work on their product for an
               | extended period of time. They will choose different
               | tradeoffs from a team that needs to adapt to higher
               | turnover.
        
         | rstarast wrote:
         | Hmm, to me it seems that 'splitBy ","' should be a function
         | that takes a string and returns a list of strings:
         | splitBy "," : String -> List String
         | 
         | so it seems "clear" that the separator should be the first
         | argument. But maybe I've just programmed functionally for too
         | long?
         | 
         | As an alternative, perhaps there's space to introduce types to
         | make this something like                 split : Pattern ->
         | String -> List String
        
           | mrkeen wrote:
           | I agree with your intuition. I'll try to make my intuition
           | explicit:
           | 
           | The 'splittee' should be the last argument. The last argument
           | is usually what you want to a) elide as part of function
           | composition, or b) loop over (the tightest).
           | 
           | E.g. Splitting a file into lines:                   lines
           | content = splitBy "\n" content
           | 
           | can be:                   lines = splitBy "\n"
           | 
           | If splitBy used the other order, it would be:
           | lines = (\c -> splitBy c "\n")
           | 
           | E.g. Splitting a file by lines and tabs:
           | entries content = concatMap splitBy "\t" (splitBy "\n"
           | content)
           | 
           | can be:                   entries = concatMap splitBy "\t" .
           | splitBy "\n"
           | 
           | If splitBy used the other order, it would be:
           | entries content = concatMap splitBy (splitBy content "\n")
           | "\t"
        
         | elwell wrote:
         | In Clojure, for functions that will probably have more than a
         | couple args, I like to pass a map, then destructure it by its
         | keys in the function definition. Two benefits are: you don't
         | need to remember the order of args, and it makes refactoring
         | easier in cases where you are simply adding a new optional arg
         | (you don't need to update all the old calls of that function if
         | they aren't using the new option).
        
           | mxz3000 wrote:
           | That's a pattern I use in a lot of Typescript, it's pretty
           | useful!
        
       | nephanth wrote:
       | 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 wrote:
         | This is impressively comprehensive 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/ 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
        
         | ducaale wrote:
         | There is https://github.com/avsm/opam-tools which aims to
         | simplify the process of setting up a local opam project with
         | all the tooling required.
         | 
         | On the topic of and janestreet-core/base and named parameters,
         | I don't like how it basically forces you to name your arguments
         | whenever you need to compose functions. I much prefer
         | Containers library which is lighter and stdlib friendly.
         | 
         | * Base/Core: List.range 0 20 |> List.map ~f:(fun x -> x * 2) |>
         | (fun l -> List.take l 5)
         | 
         | * Containers: List.range 0 20 |> List.map (fun x -> x * 2) |>
         | List.take 5
        
       | didibus wrote:
       | 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.
        
       | crvdgc wrote:
       | 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.
        
       | stark3 wrote:
       | 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.
        
       | rishav_sharan wrote:
       | 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 wrote:
         | 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...
        
       | hashbig wrote:
       | 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.
        
         | ducaale wrote:
         | This is not my first time hearing someone praising Elm's syntax
         | and standard library. How does it compare to OCaml/F#/haskell?
        
         | Kaze404 wrote:
         | 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 wrote:
           | 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 wrote:
             | 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 wrote:
               | 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).
        
             | c-cube wrote:
             | Is there any reason why a group of users didn't fork the
             | language? Lack of coordination?
        
               | Kaze404 wrote:
               | From what I've seen in HN people are more interested in
               | complaining about how Evan handles the language than
               | trying to do something about it or suggest a better
               | approach. Just makes me trust him more, personally.
        
             | quikoa wrote:
             | Yea it's too bad. If the core team was more open and/or
             | communicative I'd use Elm for production. Maybe you've
             | already seen this but there is a pretty solid blog post
             | detailing the state of Elm:
             | https://lukeplant.me.uk/blog/posts/why-im-leaving-elm/
        
         | submeta wrote:
         | Looks beautiful. Love functional languages (Elixir, Scala).
         | Python is my day-to-day language. Gets the job done. But it's
         | not my biggest passion to program in it. Too many
         | inconsistencies for my taste.
        
       | daxfohl wrote:
       | 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.
        
       | dvh wrote:
       | Noun verb. Haystack needle.
        
       | shaunxcode wrote:
       | I got excited at the idea of smalltalk syntax in functional
       | clothing but it never seemed to deliver?
        
       | jayp1418 wrote:
       | Is this being developed? How similar this is to ada ?
        
         | throwaway43234 wrote:
         | Hasn't been touched in over a year.
         | https://github.com/KeliLanguage
        
           | cridenour wrote:
           | Maybe they broke up.
        
       | ollysb wrote:
       | 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 wrote:
         | 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 wrote:
           | 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.
        
       | endergen wrote:
       | 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!?
        
         | deweller wrote:
         | But it is too late now.
         | 
         | Her: "Why did you change the name?"
         | 
         | Him: "Because I'm hedging my bets in case our relationship does
         | not outlast my pet programming project".
         | 
         | Her: "..."
        
         | avodonosov wrote:
         | New girlfriend could change her name if she is really devoted
        
         | Kinrany wrote:
         | Breaking changes after every breakup
        
         | green_apple wrote:
         | debian says hello
        
           | riffraff wrote:
           | there's also, ALIX[0] more commonly known as HURD
           | 
           | [0] https://biblioweb.sindominio.net/telematica/open-sources-
           | htm...
        
         | didip wrote:
         | 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>"
        
           | asdfman123 wrote:
           | 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 wrote:
             | > 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 wrote:
               | Shop shooting holes through lingering post-adolescent
               | cynicism!
        
         | omarhaneef wrote:
         | I don't know what the problem is. After that you only date
         | people who have the same name as your programming languages.
         | 
         | "Did something happen?"
         | 
         | "Sorry. I just had the wrong idea about you, Kaley."
        
       | adultSwim wrote:
       | The F# IDE is really good actually
        
       | ConanRus wrote:
       | >a joy for users But.. we already have H-l for that!
        
       | azhenley wrote:
       | There was some discussion on Reddit over a year ago that was
       | interesting too:
       | https://www.reddit.com/r/ProgrammingLanguages/comments/acrj9...
        
       | gridlockd wrote:
       | 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 wrote:
         | 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 wrote:
           | Kind of like if you're wearing a straitjacket, you don't need
           | to worry about accidentally punching yourself in the face.
        
       | mmphosis wrote:
       | _reads out more naturally_                 set the delimiter to
       | comma       split 1,2,3,4,5
       | 
       | or                 split 1,2,3,4,5 by comma
        
       | ogre_codes wrote:
       | This seems like a dead project. It's fairly unknown and hasn't
       | been updated in over a year.
        
         | garmaine wrote:
         | Maybe they broke up?
        
       | pbiggar wrote:
       | I'm very sympathetic to the problem. I'm working on Dark
       | (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).
        
       | sfvisser wrote:
       | 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.
        
         | pjmlp wrote:
         | Like Leksah.
        
         | dmitriid wrote:
         | > 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.
        
       | misja111 wrote:
       | 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.
        
         | adamkl wrote:
         | > _Maybe there should be a new edition of Clean Code written
         | specifically for FP_
         | 
         | I've posted links to this work-in-progress book a few times in
         | the past, but I'm going to do it again because I think it fits
         | the description perfectly.
         | 
         |  _Grokking Simplicity by Eric Normand_ [0] is a great book for
         | introducing the premise behind FP in a pragmatic fashion. It
         | doesn't get bogged down in monads and type theory, just the
         | benefits of pure functions and modeling applications as flows
         | of data.
         | 
         | All the code examples are in JavaScript, so it requires no
         | prior knowledge of functional programming, and it does a great
         | job of building things up from first principals while
         | highlighting the benefits vs a more object oriented approach.
         | 
         | It's only half complete, with a nebulous completion date, but
         | I've already purchased a copy, and it would the first book I'd
         | recommend for any newcomer to FP (it's already worth it just
         | from the first half as far as I'm concerned).
         | 
         | [0] https://www.manning.com/books/grokking-simplicity
        
         | agumonkey wrote:
         | FP abuse can lead to abstractitis which is sad but nothing the
         | Corporate World doesn't like ... it was the land of J2EE after
         | all.
        
         | dkarl wrote:
         | > 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.
         | 
         | This is a great point. I think there are a lot of open
         | questions about basic questions such as how ergonomic effect
         | systems can become and which functional programming
         | abstractions become intuitive through enough practice versus
         | always feeling confusing. I think that stuff will shake out in
         | a decade or two, and we will end up with much better styles to
         | choose from. Who wants to program in 1990s/early 2000s Java
         | style anymore? (Well, okay, a lot of people, but ignore them.)
         | Nobody would judge OOP negatively based on that mess, because
         | we know it can be done a lot better, and languages have evolved
         | to cater to what we've learned. I think functional programming
         | has a lot of evolution to come that will make it more ergonomic
         | and more practical. It will be especially interesting to see
         | what the cohort of programmers introduced to functional
         | programming via modern front-end Javascript will do as some of
         | them transition to the back end and look for statically typed
         | languages that are better than Typescript.
        
         | achr2 wrote:
         | I think the word abstraction here is overloaded. OOP is also
         | fundamentally driven by abstractions. The difference is that FP
         | abstractions are _mathematical_ abstractions, while OOP starts
         | with human-centric conceptual abstractions - the kind every two
         | year old is taught. These are not the same in terms of
         | cognitive understanding. I also use FP approaches all the time
         | in OO languages (like C#), which I believe is more aligned with
         | where the general purpose language world is moving.
        
         | platz wrote:
         | The reason why FP still doesn't really break through in the
         | corporate world is a marketing failure, in the strictest sense
         | of the word marketing, which means prioritizing the right
         | features to target the right market.
         | 
         | A large proportion of this talk is based on the book "Crossing
         | the Chasm". The book was originally written for startups, and
         | this talk adopts the book to an open source audience,
         | especially Haskell developers.
         | 
         | Gabriel Gonzalez - How to market Haskell to a mainstream
         | programmer: https://www.youtube.com/watch?v=fNpsgTIpODA
        
         | pgustafs wrote:
         | The funny thing (that I'm sure you're aware of) is that 'prefer
         | composition over inheritance' is an instance of 'prefer
         | referential transparency', an idea from FP that you should
         | always know what a variable is referencing. In OOP, this means
         | that inheritance is bad because it's not always clear what
         | functions are inherited and/or overloaded.
        
           | nybble41 wrote:
           | > an instance of 'prefer referential transparency', an idea
           | from FP that you should always know what a variable is
           | referencing.
           | 
           | The idea of "referential transparency" is that you should
           | always be able to substitute a reference for its definition,
           | or vice-versa, without changing the behavior of the program.
           | This implies both immutability (so that duplicating a value
           | doesn't change the result) and purity (so producing the value
           | has no side effects and gives the same result no matter how
           | many times you do it). It has nothing to do with knowing what
           | a variable is referencing. If anything, functional
           | programming encourages the use of generic functions which
           | don't know or care what their variables are referencing
           | (parametric polymorphism).
        
         | pjmlp wrote:
         | There is plenty of FP in the corporate world, the mistake that
         | many FP advocates make is to make it a war of FP vs anything
         | else.
         | 
         | Meanwhile multiple paradigm languages keep getting most of the
         | features that actually matter to Joe/Jane developer.
        
           | DonaldPShimoda wrote:
           | > the mistake that many FP advocates make is to make it a war
           | of FP vs anything else.
           | 
           | I don't disagree with this (goodness knows there are plenty
           | of functional purists who come across as religious zealots),
           | but I think it's also worth mentioning that there's an
           | opposing camp of people who are hard-set against ever
           | considering FP for anything at all because they've bought
           | fully into object orientation and stateful computation.
           | 
           | Both solutions are well-suited to certain kinds of problems,
           | and this opposition is well summarized by study of what is
           | called the Expression Problem[0]. A good developer should
           | know both paradigms (in addition to others!) and use each
           | where it is best suited.
           | 
           | [0] There are other issues than those discussed by the EP,
           | but the EP is, I think, the most simple perspective of the
           | distinction between OOP and FP.
           | 
           | Edit: TIL you cannot escape an asterisk on HN. That's a
           | bummer.
        
             | dashwav wrote:
             | In my experience, I have seen __much __less of the OOP-only
             | group, especially in recent years. The general feel I have
             | seen when communicating with other developers about this is
             | that OOP is a tool and it 's probably not the best one, but
             | they are comfortable with it and it's problems.
             | 
             | In general it feels like the overall feeling to FP is
             | either
             | 
             | "I don't have time to learn a new paradigm when my current
             | one is working good enough to make the company money"
             | 
             | or
             | 
             | "I love using FP ideas in my code when it makes sense"
             | 
             | I really feel like this is the ideal state for Software
             | Development, as either side "winning" will only hurt the
             | robustness of the environment.
        
               | DonaldPShimoda wrote:
               | Oh, sure! I didn't mean to suggest that there were as
               | many as the only-pure-FP crowd, though I can see how my
               | phrasing may have suggested as much. I just meant to
               | bring up that there _are_ people like that, who refuse to
               | (consciously) adopt any amount of FP in their
               | development. I have interacted with some myself. Most of
               | them make arguments about, like,  "People think in terms
               | of state so FP is inherently a bad user experience" or
               | something to that effect.
        
         | bauerd wrote:
         | >The other reason is that many FP users are too enthusiastic
         | about creating abstractions.
         | 
         | Elm lacks typeclasses, yet I've found this lack is what keeps a
         | lot of libraries at bay that would have otherwise turned out
         | overly abstract (see any mainstream Haskell library, really).
         | It's the same reasoning behind Go: With great power comes great
         | responsibility. At large, programmers shoot their own feet with
         | powerful languages. Therefore, take away their guns, ie make
         | languages less powerful. I still wish there was something like
         | Elm, but tailored for backend/network programming:
         | https://news.ycombinator.com/item?id=21909087
        
           | 1-more wrote:
           | I started with Elm, then I started working through Learn You
           | a Haskell. At first I thought the lack of typeclasses in Elm
           | was a big missing piece, but now I see the potential for me
           | to turn a programming problem into a little-too-philosophical
           | debate about the nature of truth in the universe or some
           | such. In other words leaving out typeclasses may _help_ but
           | not _guarantee_ that I keep my eyes on the screen and off of
           | my navel.
        
             | ghayes wrote:
             | The hard part with Elm's lack of typeclasses is the lack of
             | do notation. It's pretty easy to end up in Elm's version of
             | "callback hell" where you're nested several `andThen`s
             | deep. And that's for a language that doesn't have `IO`.
             | That said, I would love to try an "Elm on the backend" that
             | specifically lacks features compared to Haskell.
        
         | smithza wrote:
         | I don't see a reason why some FP languages (e.g. lisp, or
         | elisp) aren't IDE friendly. It might well be because where
         | there is unpopularity, there is less effort to integrate,
         | promote and maintain. If everything is a function and functions
         | have positional parameters and everything named can be in a
         | symbol table, why can't IDEs support (at least the basics of)
         | FP languages?
        
           | garmaine wrote:
           | Read the OP link.
        
           | simias wrote:
           | I don't know much about modern IDEs because I don't use them,
           | but I suspect that the very powerful lisp macro system can be
           | an issue for good IDE integration. Think of something like
           | the "loop" construct in Common Lisp: http://cl-
           | cookbook.sourceforge.net/loop.html
           | 
           | That's related with the problem the parent is talking about:
           | it's very easy to create DSLs in in languages like Common
           | Lisp, so people use them a lot. But for an IDE's parser, or
           | even for a new coder discovering the codebase, it's pretty
           | tricky to figure out what the code does.
           | 
           | If somebody is ultra-familiar with Common Lisp but for some
           | reason never learned how the loop construct worked they might
           | be stumped when they encounter the following code:
           | (loop for x in '(foo 2)                thereis (numberp x))
           | 
           | What does that do exactly? What will it evaluate? What will
           | it return? Which one of these symbols are special keywords
           | and which one just refer to variables or functions?
           | 
           | Meanwhile if you code in, say, C, the macro system is so
           | crappy and clunky that you basically avoid it for anything
           | complicated. Writing a similar LOOP macro in C would be an
           | absolute shitshow (not that it prevented people from trying).
           | As such C code tends to be much more verbose, but also much
           | easier to follow if you know the core rules of the language.
        
             | smithza wrote:
             | Perhaps if Macros where not such a mainstay and powerful
             | element of some FP langs (I am not arguing against them),
             | this argument would not be so strong. Macros in C/C++ are
             | difficult for IDEs to deal with too, save for constants.
             | Seeing though that macros are near fundamental to some FP
             | langs, I understand better the driver for the design of
             | Keli.
        
               | r-w wrote:
               | What gave you the idea that most FP uses macros? Much
               | code in functional languages uses no macros at all.
               | Perhaps you are confusing FP with Lisp.
        
         | solomonb wrote:
         | Fold Over a Monad? You mean like:
         | 
         | ``` ourReportAccumulatorFunc :: Monad m => m a -> m a -> m a
         | ourReportAccumulatorFunc = blah
         | 
         | ourFunc :: (Foldable t, Monad m) => t (m a) -> m a ourFunc =
         | foldr ourReportAccumulatorFunc someUnitValue ```
         | 
         | Why do you think a fold would be hundreds of lines outside of
         | the business logic?
        
           | kitd wrote:
           | Quick tip: indent 4 spaces to get code formatting.
        
         | bcrosby95 wrote:
         | I think the problem is FP has built its own set of abstractions
         | that imperative programmers aren't used to.
         | 
         | Imperative languages have slowly been adopting some of these.
         | 20 years ago you had people talking about how things like map
         | and filter are confusing but nowadays most imperative languages
         | have a version of it so obviously it isn't that confusing.
        
           | mrkeen wrote:
           | I don't know if this counts as irony, but here goes:
           | 
           | The killer feature of programming with pure functions is that
           | you can guarantee the same output for the same input. If I
           | were pushing this idea 5+ years ago, I would have said
           | "Unfortunately you have to give up your comfortable for-loops
           | and mutable variables* and learn about these weird maps and
           | folds instead, but it's well worth the trade!"
           | 
           | Fast-forward a few years and now maps and folds are
           | everywhere in the mainstream (it's even recommended to use
           | them over for-loops in many cases.) But we never got the
           | same-input-same-output guarantee which was my reason for
           | switching in the first place!
           | 
           | * Even that's being too pessimistic. You can have your
           | mutable cake and keep your guarantees, too:
           | https://wiki.haskell.org/Monad/ST#A_few_simple_examples
        
         | sfvisser wrote:
         | > 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.
         | 
         | This feels backwards to me. If I'm new and join your team I'm
         | much more likely to understand what a monad and a fold are than
         | to understand your domain specific business objects.
         | 
         | So if we are working for an insurance company and see the
         | 'Insurance' type is an instance of Monad I now know a great
         | deal about combing different insurance products into new
         | derived ones. By reading a single word of code!
        
         | cannabis_sam wrote:
         | > 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.
        
           | cuddlybacon wrote:
           | I think many of the responses to your parent post are
           | focusing too much on `fold` and not the custom monad that is
           | implied to just be a re-implementation of list.
        
           | treetide wrote:
           | I just wrote about some possible pitfalls down the ADT route:
           | https://treetide.com/posts/domain-model-pitfalls-oop-fp.html
           | 
           | > As more operations are demanded, it is more likely that the
           | existing partitioning of the world into the nice distinct
           | cases won't suit that operation anymore. Then, as a fix, we
           | can introduce more specific cases, or make existing ones more
           | general - leading to ambiguity, bloat and mental load for the
           | existing operations.
           | 
           | Just an aspect.
        
           | scarmig wrote:
           | Well, we're used to the AbstractBeanHandlerFactoryFactories
           | already. A slight discomfort of learning something new can
           | seem much bigger when you're already acclimated to abuse.
        
             | strbean wrote:
             | Posting to name-drop
             | SimpleBeanFactoryAwareAspectInstanceFactory
        
               | robocat wrote:
               | For details of the interfaces that the class inherits
               | from, see:
               | 
               | https://docs.spring.io/spring-
               | framework/docs/current/javadoc...
               | 
               | https://docs.spring.io/spring-
               | framework/docs/current/javadoc...
        
               | raegis wrote:
               | The guy next to me on the bus is asking why I'm laughing
               | so hard. I'm not sure how to respond. "These class names
               | are really funny!"
        
               | dllthomas wrote:
               | InternalFrameInternalFrameTitlePaneInternalFrameTitlePane
               | MaximizeButtonWindowNotFocusedState
        
               | philosopher1234 wrote:
               | I'm glad we got the Simple one
        
               | IncRnd wrote:
               | Sometimes, though, you can only get the desired effect
               | with SimpleBeanFactoryAwareAspectInstanceFactory_EX.
        
           | HelloNurse wrote:
           | 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.
        
             | mattmanser wrote:
             | Maybe in the 00s, but these days most languages have
             | collapsed boiler plate down massively.
             | 
             | This comes across as an old fashioned view (bordering on
             | extremely old-fashioned).
        
             | [deleted]
        
             | qppo wrote:
             | folding over a monad (or any other combinator) doesn't
             | require extra reasoning or anything clever, that's the
             | point.
        
               | chrischen wrote:
               | It does if you are unfamiliar to the pattern. It probably
               | has more to do with experience with the patterns used
               | rather than readability.
        
               | 1tCKV3QfIo wrote:
               | It shouldn't, but it does to people who get discouraged
               | because they aren't having instant success. It's like
               | anything that results in short-term regression convices
               | them it's too complex for them to learn.
        
               | JadeNB wrote:
               | 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.
        
       | tobr wrote:
       | 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".
        
       | centimeter wrote:
       | 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.
        
       | SomeoneFromCA wrote:
       | I've almost misread it as "Keil", which brought bad recollections
       | of their IDE C/C++ IDE.
        
       | fouric wrote:
       | 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.
        
       | grantjpowell wrote:
       | 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 wrote:
         | 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 wrote:
           | 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) and open
           | them into the quickfix list, then do something like
           | :%s/old/new/gce | :w | :bnext
        
         | noisy_boy wrote:
         | Having used IntelliJ, the biggest advantage of IDE for me is
         | the speed with which the errors are surfaced allowing me to
         | correct them way more quickly than I could ever do in vim. It
         | is so much more easier to find where things went wrong and how.
         | That lets me focus on the logic instead of wasting time on
         | things like fixing misspellings. Also totally agree with the
         | ease of refactoring - it basically gives you the time and
         | confidence to iterate freely.
        
         | smabie wrote:
         | This is true, especially when it comes to array languages. When
         | I was learning kdb+/q, I realized that the language was small
         | enough that I didn't need autocomplete. Also, the language is
         | so powerful that I didn't really even type that much. I would
         | have been perfectly happy writing out the code on a paper
         | napkin it was so terse.
        
           | grantjpowell wrote:
           | My observation is that I tend to like languages that I don't
           | need powerful tools to work with. That seems to be a mark of
           | a well designed language to me
        
       | barrister wrote:
       | 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#.
        
       | _raz wrote:
       | 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
        
       | leafboi wrote:
       | 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 wrote:
         | 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.
        
       | exclipy wrote:
       | Anyone else irked by the use of "Intellisense" - a Microsoft
       | brand - when "autocomplete" will do?
        
         | carlmr wrote:
         | Are you irked by Q-tips and Kleenex as well?
        
           | MrPowers wrote:
           | These are referred to as "generic trademarks" if you're
           | interested in learning more:
           | https://en.wikipedia.org/wiki/Generic_trademark. Generic
           | trademarks are studied in economics and have legal
           | implications.
        
         | 52-6F-62 wrote:
         | 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 wrote:
           | Mostly in .NET communities though, from what I've seen.
        
         | alkonaut wrote:
         | Code completion (autocomplete) is a subset of intellisense.
         | Intellisense also provides e.g. info tooltips on hover and
         | more.
         | 
         | But yes, I agree since the author specifically talks about the
         | way OO languages provide a more easily autocompleted syntax and
         | parameter help doesn't really differ, perhaps the better term
         | to use here would be autocomplete or code completion.
        
       | GrinningFool wrote:
       | Another way to solve the problem the author is looking to fix is
       | by convention:                   splitStringBy "1,2,3,4,5" ","
       | ^ action               ^ Arg1                    ^ Arg2
        
       | gmfawcett wrote:
       | 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).
        
         | dmitriid wrote:
         | Any language is non-IDE-friendly compared to what you have out
         | of the box for languages such as Java, C# and even Python in
         | IntelliJ's IDEs.
         | 
         | Most languages _at most_ have autocomplete and definitions look
         | up (and even those are often very brittle). That is a far cry
         | from what an IDE should be able to provide.
         | 
         | Granted, recently I only tried OCaml via Reason, but I remember
         | that some of the errors the compiler produces are not IDE-
         | friendly either (something like "Type A provided but elsewhere
         | wanted B" with no indication where :) ). But that's mostly due
         | to the age of the language (most "old" languages are very user-
         | hostile and have very terse/cryptic error messages).
        
           | gmfawcett wrote:
           | I agree that IntelliJ is excellent for Java, and assume it is
           | for C# (though I haven't used it for that). It's my go-to
           | tool for Java development. In my experience, it's good for
           | Python that doesn't have type annotations -- it's remarkably
           | smart really, considering the challenges of autocomplete for
           | dynamic languages -- but not truly great. Better than
           | nothing, certainly!
           | 
           | I can't speak to Ocaml in IDEs other than Emacs, but in my
           | experience, error messages are quite location-precise, down
           | to the specific word(s) on the line causing the error; and
           | the messages are readable with a little practice. They are
           | not as good as, say, Rust's error messages, but you get used
           | to them fairly quickly! But that's more a condemnation of the
           | compiler, not of the IDE.
           | 
           | There _are_ a few esoteric error types in Ocaml ( "Expected a
           | value of type 'a, but you gave a value of type 'a" -- OK,
           | that's a head-scratcher) but those are very infrequent in
           | typical code.
        
             | octachron wrote:
             | Do you have a recent example of an error of the form
             | "Expected a value of type 'a, but you gave a value of type
             | 'a"?
             | 
             | I have hoped to have eliminated all of them in 4.08.
        
               | gmfawcett wrote:
               | That is great news, and I am probably remembering errors
               | from the olden times. :) Thanks for your work!
        
         | hashbig wrote:
         | 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.
        
           | andrepd wrote:
           | What an odd comment.
           | 
           |  _> Compare that to JavaScript where you can literally just
           | install vscode and node and you're up and running_
           | 
           | As opposed to OCaml where you... install opam and merlin and
           | you're up and running?
           | 
           |  _> Not to mention that you could pop open a console in any
           | browser and execute code._
           | 
           | As opposed to OCaml where you can pop open utop and execute
           | code.
           | 
           |  _> For something to be simple, a 10 year old kid needs to be
           | able to figure it out._
           | 
           | How many 10 year old kids are there working as professional
           | programmers? Come on...
        
             | hashbig wrote:
             | > How many 10 year old kids are there working as
             | professional programmers?
             | 
             | Many of them in 10 years time, and they will be using
             | concepts they learned when they were 10. And FP enthusiasts
             | would complain why no one uses their favourite language.
             | 
             | My point is, if we want to get more people to use FP we
             | have to make it more accessible. Everything from building
             | better tooling, tutorials, environments. Good languages
             | alone don't matter.
             | 
             | You can't tell me that it's just as easy to get started
             | with JavaScript or Python today as it's to start with
             | OCaml. That's just delusional.
        
               | smabie wrote:
               | I actually think it's easier. dune and opam are so much
               | nicer than python/pip/conda or whatever.
               | 
               | Have you used OCaml? Because you can set up a complete
               | environment with IDE support in like 5 minutes flat. It's
               | actually one of the easiest environments to set up of any
               | language. dune, merlin, opam, and utop provide everything
               | you would possibly need.
        
               | gmfawcett wrote:
               | It would be nice if 10 year olds can be exposed to
               | functional programming. But it's hardly a necessary
               | prerequisite. There are plenty of technologies that
               | people adopt later in life and which are hugely
               | successful (SQL/RDBMS is a great example).
               | 
               | If you want to expose 10-year olds to functional
               | programming, Logo [1] is a great place to start, and has
               | been for decades. That's where I picked it up (I didn't
               | know it at the time, but looking backwards it's now
               | clear).
               | 
               | [1] https://en.wikipedia.org/wiki/Logo_%28programming_lan
               | guage%2...
        
           | gmfawcett wrote:
           | 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.)
        
           | carlmr wrote:
           | >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.
           | 
           | That's only because VSCode was developed in JavaScript, and
           | JavaScript is used in Browsers anyway. This has nothing to do
           | with Intellisense friendliness.
        
             | hashbig wrote:
             | No, golang is just as easy to install and work with on
             | vscode. Just install Go and the official Go plugin and you
             | have an IDE experience complete with debugging, formatting,
             | and intelligent autocomplete. It has nothing to do with
             | vscode being written in JS.
        
               | pjmlp wrote:
               | Same applies to F#, a ML based language.
        
               | carlmr wrote:
               | You didn't mention plugins, it seemed like not having to
               | do anything besides installing the language and VSCode
               | should be required.
               | 
               | In that case there are many functional languages with
               | good IDE support. E.g. F# through Ionide.
        
         | carlmr wrote:
         | Also F# has amazing IDE support with Ionide in VSCode.
        
       | hellofunk wrote:
       | 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 wrote:
         | Any chance you have a write up about your experience with it??
        
           | bboy13 wrote:
           | 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.
        
             | linkdd wrote:
             | Do not underestimate oneliners
        
             | throwaway43234 wrote:
             | I agree it's probably a joke, but I'm not so sure that the
             | core idea is actually impossible... I could reasonably see
             | a SaaS that simply provides a quick and dirty key-val
             | store. The code is just a translation from REST to REDIS
             | which could easily be done in 2 lines, the value-add is the
             | hosting.
             | 
             | That'd actually be pretty helpful for initial prototyping,
             | where you want to have state shared across devices but
             | don't want to bother with hosting a backend at first, and
             | localhost wont work because the client wants to play with
             | it too.
        
             | IncRnd wrote:
             | Of course this is a joke.
        
             | lostcolony wrote:
             | 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.
        
             | mst wrote:
             | _APL programmer bursts through the window_
             | 
             | "ACTUALLY! ..."
        
       | whateveracct wrote:
       | Wadler's Law at work
        
       ___________________________________________________________________
       (page generated 2020-08-31 23:00 UTC)