[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)