yiyus 9 days ago [-]
There is not a single example in the README. I checked the step-by-step guide, but it starts with installation and documentation instructions, then imports, and I don't know yet how the language feels like. Ok, let's check that handbook then. Computation model, type system, ...

Please, I just want to see a program with a dozen lines of code to see what it looks like. Of course, more extended examples with the intended usage would also be very welcomed.

I eventually found this: https://github.com/kocircuit/kocircuit/blob/master/lessons/e... but I think it should be much easier to arrive there.

giancarlostoro 9 days ago [-]
The law for making a new language: always include examples up front.
erwan 9 days ago [-]
For anything you want other people to use really
sn41 9 days ago [-]
Even in pure mathematics, a good rule is to give examples (if simple) right after the definitions. Examples always help.

Here's a post by the Fields medallist Tim Gowers:

https://gowers.wordpress.com/2007/10/19/my-favourite-pedagog...

agumonkey 9 days ago [-]
Unless you want to filter for the most determined only !
neuland 9 days ago [-]
This was my first reaction too. There are also no links between the steps. So, you have to go back and click to the next step from the file list.
desireco42 9 days ago [-]
Thank you for linking to example, I has same thoughts.

Also, looking at installation instructions, it is bootstrapped by Go, so it does seem it is still in some prototype phase.

I would say, let's give them a year or two.

Language, as language, looks clear enough for me, but it is hard to judge from little I saw.

staticassertion 9 days ago [-]
Thanks, came to the comments hoping someone could point me to code - I wasn't having any luck at all.
mshockwave 9 days ago [-]
Can't agree more. The readme/lessons looks very "academic" but I just want an overview.
nikofeyn 9 days ago [-]
isn't this a little demanding and entitled? for example, the submitter of this post to hacker news may not be the creator of the language and repository. so the creator is off just having some fun creating a language, with more than minimal documentation, and uploads it to github to track changes and generally make it public. then someone thinks it's interesting and posts it here, and the top comment is someone with too aggressive of a tone, in my opinion.
kierenj 9 days ago [-]
I don't think it's aggressive at all. They're literally presenting a language. A language. They talk about its virtues but I mean come on, how do you introduce a language?

Bonjour!

mcphage 9 days ago [-]
> isn't this a little demanding and entitled?

No.

The poster shared it to HN because they want other people to look at it. Which is fine, but they're asking for our attention, and they need to respect that fact—and us—and not waste our time. Sharing a new language but making us dig around to understand one of the most fundamental things about the language—what the code looks like—does not respect us, our time, or our attention. If that's a problem, they can keep it a private repo, and not share it on HN.

nikofeyn 9 days ago [-]
you missed my point of the poster not necessarily being the creator of the repository.
andrewflnr 9 days ago [-]
The point of posting things on a site with comments is so people can comment on them. Even if we knew for a fact that the poster wasn't the creator, it would still be appropriate to comment on an annoying aspect of the project.
V-2 9 days ago [-]
Poster's user handle is petar, and petar happens to have merged the latest PR in Ko repository, so I'd say there's a pretty good chance it is the same person.
yiyus 9 days ago [-]
I am quite sure the reason my comment is at top is not because other readers appreciate my tone (which I don't find aggressive, although I admit it could be nicer) but because of the link.
ivoras 9 days ago [-]
I can't be the only one who's annoyed by language writers introducing arbitrary uncommon syntax apparently just for the sake of doing something new?

Lua's great little language but writing ~= instead of != is simply annoying. In this "Ko" language, it looks like they do returns with a colon, as in "return: x" -- why??? I won't even go into Rust picking up Perl's bad habit of looking like line noise with all the ASCII sigil usage in advanced code.

Also, any language which doesn't have a "hello world" example in its front page is doomed. Even such a wide-spread language as Python has code snippets practically first thing on its web page! This is not by accident!

alan-crowe 8 days ago [-]
I wonder why they preferred ~= over =/= ?

I would sympathize with using =/= for "not equal" because it is ASCII art for the traditional mathematical notation of using an equal sign with a line through it. Though it might be better just to permit carefully selected unicode characters such as https://www.fileformat.info/info/unicode/char/2260/index.htm

=/= is disappointing as art because it is too wide, but it has obvious mnemonic power.

Would you object to =/= as "arbitrary uncommon syntax" because it is poor art? Does its mnemonic power save it from the criticism of being "new for the sake of new"

fanf2 6 days ago [-]
MATLAB also uses ~= but I am not certain that is where Lua got it from. (The paper on the history of Lua does not say...)
tombert 9 days ago [-]
I don't want to be "that guy", but a small sample in the README would be nice. Tough to tell if I'll like a language if I can't even see it without traversing through the docs.
choeger 9 days ago [-]
But what's its type discipline? H/M polymorphism? Overloading? Subtyping?

How is it evaluating? Eager? Lazy?

What values are supported? Records? What flavor? Modules?

rhencke 9 days ago [-]
You may find the Ko Handbook useful, as much of this is addressed there:

https://kocircuit.github.io/language/

kyleperik 9 days ago [-]
I love the generic function aspect of this, where there aren't necessarily specific inputs or outputs. This will make code reusable by factors. A simple use being not needing to define both `toRadians` and `toDegrees`, just definite the relationship. But I believe this can be taken to the point of getting backpropagation for free once forward propagation is defined in neural networks.

Not to steal any thunder, but I've been prototyping a language very built on this idea.

https://git.kyleperik.com/kyle/judo

theoh 9 days ago [-]
I could be jumping to an incorrect conclusion, but I think you are misreading the description of Ko's genericity. It doesn't mean that inputs and outputs are not distinguished. It just means that arguments and return values aren't explicitly typed. The kind of Prolog-style unification you are talking about is something different.
kyleperik 9 days ago [-]
You're right. This sentence and the general syntax of the language mislead me

> Genericity means that functions do not have to declare argument and return value types, which makes them highly reusable.

Thanks for being kind about pointing out my massive presupposition

vmchale 9 days ago [-]
Is this a research language? I don't understand how this offers anything beyond what already exists.

I'm also suspicious of the fact that it's implemented in Go. I would think that someone who knew functional programming well enough to create a new language would implement the language in Haskell or OCaml or even Standard ML.

Also the type system looks pretty bad. No algebraic data types.

Blackthorn 9 days ago [-]
What a bizarre criticism. Most of the newer popular functional languages aren't implemented in those, but rather Java, and for the same reason given in the readme for Go.
haggy 9 days ago [-]
> Most of the newer popular functional languages aren't implemented in those, but rather Java

Well, that's not entirely correct. I assume you mean they run on the JVM? Language like scala are actually written IN scala. The only thing that is in java is the interpreter but the entire compiler is scala.

Blackthorn 9 days ago [-]
True enough for Scala, but Clojure has plenty of Java code.
phyrex 9 days ago [-]
OTOH clojure script is completely written in clojurescript
vmchale 9 days ago [-]
> Most of the newer popular functional languages aren't implemented in those, but rather Java,

I don't think this is true. Java is not a good language for compilers in any case, and it would cause me to trust the language less, especially if they were claiming it was a "functional programming language"

angara 9 days ago [-]
> Java is not a good language for compilers

Could you elaborate?

heavenlyhash 9 days ago [-]
> would implement the language in {foo}

If that choice becomes perceivable to anyone but the authors and maintainers of the language itself, I'd say that's a first class failing, isn't it?

The quality of a language should be a pure function of the language itself; the interpreter doesn't (or rather, shouldn't) enter into it.

owaty 9 days ago [-]
I think the GP has the following causal diagram in mind:

               +---------------------+
               | Author's competence |
               +-------+-----+-------+
                       |     |
                       |     |
    +--------------+   |     |   +---------+
    |Implementation| <-+     +-> |Product  |
    |  language    |             |language |
    +--------------+             +----+----+
                                      |
                                 +----v----+
                                 |Language |
                                 |quality  |
                                 +---------+

So you are both right; language quality is a function of the language itself, but if we don't yet know much about the language or its author, there is a correlation ("confounding") between language quality and the choice of the implementation language, so if that's the only information we have, might as well take advantage of it.

I am not weighing in here on what specifically the choice of Haskell, OCaml, or Go say about author's competence; I am simply addressing your point that the choice shouldn't matter at all—unless you are convinced that the knowledge of PL theory and design principles is uniformly distributed across all language communities.

zzzcpan 9 days ago [-]
Except that Haskell and OCaml as implementation languages would signal huge academic bias and therefore likely inability to come up with a usable language or at least there exists a negative correlation with those languages.
vmchale 9 days ago [-]
> Haskell and OCaml as implementation languages would signal huge academic bias

Apparently reading papers from the past 30 years is a "huge academic bias."

I'd honestly be fine if it was implemented in Racket too.

> inability to come up with a usable language or at least there exists a negative correlation with those languages.

No one has ever actually offered me a substantive argument that Haskell is unusable. It always seems to be "well, I don't personally understand it, and that means it's unusable" Uhh okay.

Profan 9 days ago [-]
Just as a sidenote, Rust's compiler was first implemented in OCaml after all, is Rust "academic and unusable"? ;)
Ws32ok 9 days ago [-]
I don't agree with "unusable" but "academic" probably has some justification.

The fact that it has a "let" keyword does make it "academic" to me. I'm fairly sure we can now have compilers that don't need such hints to be explicitly provided. Rust enjoys its let keyword so much they have a "If let" syntax.

Languages that use random punctuation without providing real benefit could also use a cleanup. Lua with ~= is a good example: Tilde in mathematics means "approximate". In C != means "not equal". So lua's designers can be accused of either never seeing C or deliberately choosing something different. Given that Lua is implemented in C they can't easily claim ignorance.

Archaic and awkward ways of expressing code shouldn't be propagated into new languages unless here is a clear benefit. Have a look at Erlang. Excellent overall but has lots of old warts from yesteryear you wouldn't want in a modern language. Eg look at its string syntax / naming rules. Now compare it to Elixir. Modern. Same VM.

Moving with the times is useful. Future languages shouldn't be adding debris everywhere just to be different.

steveklabnik 9 days ago [-]
“let” us a required feature of the Rust grammar; the semantics would be significantly more complex without it, making tooling harder, etc. we didn’t add it for no reason.
Ws32ok 7 days ago [-]
Complexity often masks a lack of search for simplicity. Or was "let" the simplest answer?
steveklabnik 7 days ago [-]
It's not a matter of "search for simplicity"; the grammar is just inherently ambiguous without some sort of token in this position. let was taken from OCaml, where a lot of inspiration from Rust came from.

(As a reader, it's also really nice to be able to see "there's a new variable being created here" at a glance. Ambiguity is a human problem as well as a computer problem.)

akvadrako 9 days ago [-]
More than more languages, yes.
dmix 8 days ago [-]
That worldview on OCaml and Haskell = academia only is pretty out-of-date these days...
dmix 8 days ago [-]
What does GP stand for? I keep seeing it around HN. I'm assuming it's a variation of OP?
vmchale 9 days ago [-]
I'm mostly just saying "if the authors were experts on functional programming, surely they would use Haskell or OCaml?" My problem is not with the compiler/implementation but rather the fact that they are trying to sell a new functional language without having taken stock of the existing offerings.
zem 9 days ago [-]
they are trying to build on top of the go runtime, so implementing it in go makes sense.
samatman 9 days ago [-]
I just want to say that "Ko" is an excellent name for a deadlock-free language written in Go. Kudos.
iainmerrick 9 days ago [-]
Ha! I didn’t even notice, thanks for the hint.
thosakwe 9 days ago [-]
weberc2 9 days ago [-]
This is interesting. I see it has an interpreter, but it's unclear at a glance whether "interpreted" is the default production mode of the language or if the interpreter is available to facilitate a repl or smething.

Skimming some of the .ko files, I like that it seems readable and familiar (even if there are some oddities). No matter how much time I spend with Haskell and OCaml, I always spend conscious effort trying to mentally parse the source code.

notduncansmith 9 days ago [-]
This reminds me a lot of a library I wrote called Factfold (https://github.com/notduncansmith/factfold).

Something I noticed while working on it is that the declarative style is not always the most comfortable way to describe things, and well-written imperative code is declarative in its own way. Somewhere in most useful programs, it helps to have the imperative escape hatch until you can support the best declarative expression.

heavenlyhash 9 days ago [-]
Interesting.

Random observations in no particular order:

- The simple assignment syntax looks somewhat procedural and is easy to read in small hunks at a time, but is still functional. I like this. This meshes well with the very real limits of how the human brain can parse things.

- I wish there were type declarations. There's a type system, but it seems to be all inference. Type declarations just at the function inputs and outputs (and leaving it pure inference in the middle) would promote readability when you've got no compiler in hand and are just eyeballing the pure text, in my opinion.

- I'm surprised by the inclusion of a system of nonlocal returns (panic/recover). It still looks relatively functional, but A) boy that's not an area where the word "relatively" is comfortable to use and B) I shudder to think what the inferred types will tend to explode into when using this feature (an Either of an Either of an Either of a ...?) in a nontrivial program (and the examples don't really shed light on that either, due to the "all inference" model leaving us with no plain text declarations of types in sight).

- I haven't seen any examples yet of what happens and how you're supposed to resolve it when the type inference can't quite figure it out. There seem to be some examples of doing explicit casts which seems to be a workaround for this, but I don't see it discussed very clearly.

- The quick and easy syntax for returning new record/structure types seems nice. Though I'm again a tad worried that the range of types I could end up producing would get pretty large.

- The syntax holistically seems to keep things from "drifting to the right", which seems to be a common readability cramp that emerges in many functional languages. Nice.

- Using the term "Variety" for roughly "closure" is... very nonobvious to me. But I shouldn't nitpick on terminology. (And for what it's worth, I read the protobuf that Ko uses internally to define its types of types before anything else, and so maybe I'd be less surprised if I had encountered it from from the docs and lessons first.)

Caveat: these are all "hot takes" from the couple dozen minutes of digging I've done so far. I might be reading some things wrong or have missed some documentation, so take these comments with a grain of salt and do your own looking as well.

Overall, this seems neat, but simultaneously leaves me a little worried that I'd be able to too easily write things in which the type inference finds something that compiles, but isn't the type that I would've declared.

I'd be really interested to see what this shapes up like if combined with some system for explicit type declaration. Gluing Ko together with a serial data schema like Protobuf and using Ko for "migrations" seems like it could be a really useful combination, for example.

nine_k 9 days ago [-]
Yes, type declarations are documentation, and tell me about as much, or more, about a function than its name, when reading e.g. Haskell code. They are a necessary usability feature.
minionslave 9 days ago [-]
Would it be possible to have a small hello world example in the README?
simcop2387 9 days ago [-]
Couldn't find it easily, but what model are they using to make this dead-lock free as they advertise? I've seen a number of languages try to accomplish this same goal but usually with a huge caveat on what kinds of programs are allowed, or by randomly killing threads when a dead-lock is detected.
Syzygies 9 days ago [-]
If you understand why a purely functional language like Haskell rocks at parallelism without worrying about deadlocks, then: same answer here.

I'll agree this isn't ready yet to be the first example of functional parallelism in someone's life, but I'm pretty excited to play with this computational model.

simcop2387 9 days ago [-]
Even with Haskell you can still have deadlocks [1]. They give you the tools to write code that you can prove won't have them, but restricting the kinds of programs you can write. But it's an opt-in thing, it's not a promise of the language that you can't do it. Rust is trying to do a similar thing, but it's still also possible to write yourself into a corner with deadlocks if you work against the feature.

Another language I saw recently that has this promise was Pony which uses an actor and message passing model to try to accomplish this but it doesn't actually prevent you from hitting the case, instead it'll just kill a random actor until the deadlock is gone [2]. This can work but it needs to be up front that you MUST write your software to be ready to be killed at any time and continue to function.

It's really an impossible situation to completely "solve", given that doing so would require a solution to the halting problem. So it's always a fun place for me to start looking at any new language if they talk about locks and dead-locks. So far I think Haskell and Rust (and probably other ML family) have the best balance being struck since you can opt in to statically proving this if you restrict those parts of your program but you're not required to do so by the language itself.

[1] https://www.fpcomplete.com/blog/2018/05/pinpointing-deadlock... [2] https://news.ycombinator.com/item?id=9485333

9 days ago [-]
jerf 9 days ago [-]
Hot takes, as someone else says:

https://github.com/kocircuit/kocircuit/blob/master/lessons/1... : You might want to consider using Go syntax whenever it is not a problem. 'import "package" as foo' rather than 'import foo "package"' is just pointless change, unless there's more to the "as" statement later.

https://github.com/kocircuit/kocircuit/blob/master/lessons/1... : Whoa, I have to type the name of all the arguments I want to use to every function on every invocation? That's a level of noise I'm not interested in. In https://github.com/kocircuit/kocircuit/blob/master/lessons/1... it is claimed this is necessary to support default arguments, but see Python's function argument invocations. (And be sure you see all of it; for instance, it is little known that you can:

    >>> def f(x):
    ...     return x * 2
    ... 
    >>> f(x = 2)
    4
that is, even a positional parameter can be passed by name if you insist.)

Coming back after reading on, I see you let Eq and Sum and such get by without argument names. Generally a language should not reserve privileges for itself that it does not grant to its users without a really good reason.

https://github.com/kocircuit/kocircuit/blob/master/lessons/1... : I literally have no idea how you are using the word "monadic" in this section; it is neither the proper mathematical term, nor the very close Haskell term, nor any subsequent misunderstanding I've ever seen of the Haskell term ported into other languages, nor can I particularly connect it to the philosophical meaning, nor do I (glancing ahead) see any other documentation for it. My search was not exhaustive, but taking such liberties with a term like that sets off a lot of flags for me.

https://github.com/kocircuit/kocircuit/blob/master/lessons/1... : This is, IMHO, a rather dirty hack around trying to copy the way pure Haskell code can implement definitions without much concern for order, while at the same time having side effects in the code. That "DoubleGreeting" on the bottom is getting really ugly (and I mean in terms of the semantics of what is being represented there, not the surface syntax layer), and it's still in the sample code, where things should be looking artifically fake-pretty because the real-world hasn't intruded yet. It's a solution to a problem that shouldn't have been introduced in the first place.

https://github.com/kocircuit/kocircuit/blob/master/lessons/3... : I expect "repeated assignment" will be difficult to follow with nested structures. Also, what happens if I move yearOfBirth below the repeated "occupations"? My point here is not that there isn't an answer; it's that I can come up with 3 or 4, which is the real problem.

https://github.com/kocircuit/kocircuit/blob/master/lessons/3... : Variety is a bad name for this concept. It's too close to the well-defined "variant" term and causes serious concept clash in my head. "Function object" or something, maybe. "Closure" might work, haven't studied it closely enough to be sure.

https://github.com/kocircuit/kocircuit/blob/master/lessons/3... : This appears to mean that the "null" value is forced into all types, which makes this, surprisingly, even worse than Go itself on this front, which at least has a few types of values that can't be null.

https://github.com/kocircuit/kocircuit/blob/master/lessons/3... : At scale, you can't provide a generic hashing function. It's appealing, but it really can't be done. At best you can provide an interface. Don't even provide a default implementation. Java has had a long history of problems with that.

General comment: Using the functions for flow control is OK, but combining that with arbitrarily-reorderable function argument parameters is crazy. Anyone who writes If(else: ..., when: ..., then: ...) is just insane anyhow, so don't even allow it in the syntax/grammar, because it will happen. It seems to me you basically have an imperative language trying to look functional, while I see little to nothing "functional" about it, and you'd be better off just being an imperative language and take advantage of structured programming's implicit control flow <-> source code layout correspondence. You're paying the price for some things you're not successfully taking advantage of.

https://github.com/kocircuit/kocircuit/blob/master/lessons/5... : Re: arg0, arg1, arg2, etc., another solution to a problem that should simply have not been introduced.

My summation is that even in the examples, I'm seeing a lot of little quibbles stack up and become some big problems, and that's before I'm trying to actually code in this. I'd suggest some more thinking about the language's goals, and ensuring that every feature is in harmony with that goal and everything not necessary for it has been cut, because that is not where this language is right now.

Eli_P 9 days ago [-]
What's the main advantage of Ko over Go and Pony[1]? I never coded in any of them, but looks interesting.

[1] https://www.ponylang.io/discover/

pier25 9 days ago [-]
Is this like Haxe?
jackhalford 9 days ago [-]
.ko is already used for kernel objects :(
chrisseaton 9 days ago [-]
Many file extensions are in multiple use. There's only so many two or three letter permutations.
timbit42 4 hours ago [-]
File extensions aren't limited to 3 characters these days.
pulsarpietro 9 days ago [-]
Y.A.U.L.
hota_mazi 9 days ago [-]
"Active development" but the last commit was two months ago...