Live data from Hacker News

Idris 2 0.6.0 is now available for the JVM

github.com

41–50 of 65 posts

Re: Idris 2 0.6.0 is now available for the JVM

#41

Earlier quoted context omitted.

the type `null | true | false` is different from `true | false`, a type checker can assert that you handle the `null` case before using a function that wants a boolean. This is how rust handles it (with the Option type).

In particular, you may want this to signify “I dont know” with NULL, just as in SQL. See the Wikipedia page for ternary logic for more info.

Note that 3VL (3 valued logic) is one of the more criticized aspects of SQL.

3VL is a gigantic leap of of complexity over 2VL (boolean). The number of possible operations is a lot higher and the choice of operations is not standardized. To quote wikipedia: "In two-valued logic there are 2 nullary operators (constants), 4 unary operators, 16 binary operators, 256 ternary operators" And we all agree which of those 16 is named what. "In three-valued logic there are 3 nullary operators (constants), 27 unary operators, 19683 binary operators, 7625597484987 ternary operators" There is no standard meaning of the 3'rd value and of the operations involving it.

That is not to say that 3VL isn't useful. I believe the reason for the criticism of 3VL in SQL it that the system made those choices for you and those choices are not always intuitive. Therefore a null in one attribute in one relation might mean something very different from a null in another attribute in another relation.

Also note that as opposed to digital signal processing (where binary and ternary refer to the number of possible values a bit/trit can have), when discussing logic arity (nullary, unary, binary, ternary, n-ary) refers to the number of arguments required by a function as opposed to the number of values the arguments can have (univalent, bivalent, trivalent, k-valent). This is confusing because the terms are used interchangeably.

Re: Idris 2 0.6.0 is now available for the JVM

#42

Idris 2 is a purely functional programming language with first class types. This repository provides Idris 2 compiler targeting JVM bytecode so that Idris 2 compiler and Idris 2 programs can run on the JVM

To slightly elaborate: when this comment say "first class types" they're referring to dependent types. For programmers who are not aware: think about functions in functional programming languages. They're "first class citizens" in the sense that there is no difference between functions and any other values, such as `3` or `"hello"`. In dependently types languages, there is no difference between types and other values. Types are just any other value. For example, normally `Int` would be a type, but in these kind of programming languages `x: Int, x > 5` would also be a type even though the type depends on the value `x`.

In terms of software engineering, one bonus you get is being able to encode your unittests in your type system. For example, you can do (in Agda):

  _ : myFunction x y z == 33
  _ = refl -- refl is of type `x == x`
and compiler will run this test for you at compile-time while type-checking your program.

Two popular "practical" dependently typed languages are Agda and Idris. Of these two, Idris is relatively designed for software engineers, whereas Agda also wants to be a state-of-the-art automated theorem proving tool. I would strongly recommend checking both if you want to explore this area of programming languages. I wrote practical programs in Agda (e.g. language parsers, JSON parser etc) and I think it can make a programmer extremely productive, if you like this kind of workflow. Correctness is very easy to reason in these languages, and although it may look daunting at first, writing practical programs are very approachable (about as hard, maybe ever-so-slightly harder than writing code in Haskell). Have fun!

Re: Idris 2 0.6.0 is now available for the JVM

#43

Earlier quoted context omitted.

> Just like `zero | one | two` is not equivalent to `Option ` Isn't it ? both cases represent a type than can express 3 variants

Those two types are indeed equivalent by themselves. The problem comes when you want to store them somewhere nullable. `zero | one | two | zero` flattens back down to `zero | one | two`, you can't distinguish between the two zero/null cases. On the other hand, `Option >` allows you to distinguish between None and Some(None). This makes union types unsound in the presence of type parameters/generics. TypeScript suppor…

> This makes union types unsound in the presence of type parameters/generics.

I'm not sure if "unsound" is a good adjective here. There are cases where this is actually desired behaviour and the rules can definitely be "sound".

For example, I might want to know what errors can appear, but not care where they come from. So `ErrorA | ErrorB` is what I want to see, not some nested structured that allows me to differentiate where ErrorA came from in case that there are multiple possible options.

Re: Idris 2 0.6.0 is now available for the JVM

#44
post #22

I am wondering what kind of implications there are for Idris 2 to run on the JVM. For example: Does it still have TCO on the JVM? What about data structures? Does it have a set of functional data structures implemented, on top of Java ones? Or is it all implemented on top of Idris 2 "primitives"?

Naturally it doesn't have TCO on JVM, at least not natively as bytecode representation for it. The only possibility is to rewrite the code in similar way as clojure and Scala do it.

Which, to be clear, is not a zero-cost mechanical translation, and can be tricky and annoying when you start talking about things like generic monad transformer stacks.

Re: Idris 2 0.6.0 is now available for the JVM

#45

Earlier quoted context omitted.

I think TCO and JVM are orthogonal discussions -- by the time the bytecode is generated, the TCO may have already been performed.

I'm actually not sure about that. I think the Javascript compiler target also lacks full TCO. The Idris 2 compiler itself I think does not perform this optimization, because the Scheme reference backend does it already. I might be wrong about that, but I remember several active unresolved discussions on this topic in the community last year. I haven't been involved actively in it for several months, so my memory migh…

The javascript back end handles mutually recursive tail calls. It finds connected components and rewrites them to use a trampoline-like thing. There is a nice explanation of how it works at the top of the file:

https://github.com/idris-lang/Idris2/blob/main/src/Compiler/...

One could argue that it's not "full" TCO, but it does cover a lot of use-cases. That rewrites to NamedCExp, so it could be reused by other backends.

The Java backend seems to be doing its own thing. There aren't a lot of comments or documentation in that repository, but I do see evidence that it's doing something interesting in src/Compiler/Jvm/Optimizer.idr:

    Pure $ if shouldTrampoline && hasNonSelfTailCall tailCallCategory
      then trampolineExpression True inlinedAndTailRecursionMarkedExpr
      else inlinedAndTailRecursionMarkedExpr

Re: Idris 2 0.6.0 is now available for the JVM

#47

Earlier quoted context omitted.

That doesn’t make sense. `null | false | true` is not equivalent to `Option ` or `Option `. Just like `zero | one | two` is not equivalent to `Option `. Assuming that `true | false` is equivalent to something like `enum { true, false }`.

> Just like `zero | one | two` is not equivalent to `Option ` Isn't it ? both cases represent a type than can express 3 variants

No.

There is an isomorphism between them, but they aren’t equivalent since for one you will have to match on the `Option` first in order to see whether it is `None` or `Some(Next)` and then inspect `Next` (if `Some(…)`).

Same reason that `Nothing | Pointer` is not equivalent to `Option`. And it makes a huge practical difference, since the first type allows for “nothing-pointer dereference” while the second one does not.

Re: Idris 2 0.6.0 is now available for the JVM

#48

Idris 2 is a purely functional programming language with first class types. This repository provides Idris 2 compiler targeting JVM bytecode so that Idris 2 compiler and Idris 2 programs can run on the JVM

To slightly elaborate: when this comment say "first class types" they're referring to dependent types. For programmers who are not aware: think about functions in functional programming languages. They're "first class citizens" in the sense that there is no difference between functions and any other values, such as `3` or `"hello"`. In dependently types languages, there is no difference between types and other values…

So I could also write all my code purely in the type system too, right?

Re: Idris 2 0.6.0 is now available for the JVM

#49

Earlier quoted context omitted.

> Just like `zero | one | two` is not equivalent to `Option ` Isn't it ? both cases represent a type than can express 3 variants

No. There is an isomorphism between them, but they aren’t equivalent since for one you will have to match on the `Option` first in order to see whether it is `None` or `Some(Next)` and then inspect `Next` (if `Some(…)`). Same reason that `Nothing | Pointer` is not equivalent to `Option `. And it makes a huge practical difference, since the first type allows for “nothing-pointer dereference” while the second one does…

> And it makes a huge practical difference, since the first type allows for “nothing-pointer dereference”

That's not how strict TypeScript works. If you have a nullable you'll need to prove to the compiler first that it is not currently null before dereferencing.

Re: Idris 2 0.6.0 is now available for the JVM

#50

Earlier quoted context omitted.

To slightly elaborate: when this comment say "first class types" they're referring to dependent types. For programmers who are not aware: think about functions in functional programming languages. They're "first class citizens" in the sense that there is no difference between functions and any other values, such as `3` or `"hello"`. In dependently types languages, there is no difference between types and other values…

So I could also write all my code purely in the type system too, right?

Yes, all computation done at runtime can be done at compile time (within type system).

This is a problem in some cases e.g. if you write an infinite loop, this would mean compilation will infinitely loop. Different languages deal with this problem differently. E.g. in Agda, there is a "safe" subset of language that is not Turing Complete such that all programs can be algorithmically proven to be halting. But you can work around this via pragmas. Speaking from experience, the safe subset of Agda is all you need to write useful programs. You just need a tiny shell (maybe only few lines of code) that will handle IO and Haskell FFI. The rest of the code will be purely functional, safe, Turing Incomplete Agda.

Post reply on HN